std::find / find_if versus for loop

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • ma740988

    #1

    std::find / find_if versus for loop


    Trying to get more acclimated with the use of function objects. As
    part of my test, consider:

    # include <vector>
    # include <iostream>
    # include <algorithm>
    #include <stdexcept>
    #include <bitset>

    using std::vector;
    using std::cout;
    using std::endl;
    using std::ostream;

    using std::bitset;

    class bar {
    int iden;
    public:
    bar(int id) : iden(id) {}
    int get_id() const { return iden; }
    };
    class my_foo {
    typedef std::vector <bar> BAR_VEC;
    BAR_VEC bv;

    public:
    my_foo()
    {
    bv.push_back(ba r(0));
    bv.push_back(ba r(1));
    bv.push_back(ba r(3));
    }
    void find ( int id_to_find )
    {
    BAR_VEC::const_ iterator end = bv.end();
    for ( BAR_VEC::iterat or it = bv.begin(); it != end; ++it )
    {
    if ( id_to_find == it->get_id() )
    {
    std::cout << " found " << id_to_find << std::endl;
    }
    }
    // BAR_VEC seg_iter = std::find(
    // bv.begin(), bv.end(),
    // XXX ); // XXX now the fancy functor or predicate business - i
    suppose

    }
    };


    int main()
    {
    my_foo m;
    m.find( 0 ) ;
    m.find( 1 ) ;
    m.find( 9 ) ;
    }

    Now within the find function. I'd like to use std::find or
    std::find_if to achieve the same result as the for loop but I'm
    getting wrapped around the axle trying to 'plug' a parameter/functor
    into the third argument of find.
    Again this is pure experiment. Perusing a text here and I'm just
    trying to create examples as I go along, in an attempt to embrace
    different views of iterating across containers/ (where necessary ) call
    member functions etc. beyond the convential for loop.

  • cbsmith@gmail.com

    #2
    Re: std::find / find_if versus for loop

    There are different ways to go with this, but I'd go with something
    like:

    struct IsId : public std::binary_fun ction<int, bar, bool> {
    bool operator()(int anId, const bar& aBar) const {
    return anId == aBar.get_id();
    }
    };

    BAR_VEC::const_ iterator seg_iter = std::find_if(bv .begin(), bv.end(),
    std::bind1st(Is Id(), id_to_find));
    if (seg_iter != bv.end()) {
    std::cout << " found " << id_to_find << std::endl;
    }

    IMHO it's prettier if you use std::for_each, but this approach has the
    more efficient fast failure.

    --Chris

    Comment

    • ma740988

      #3
      Re: std::find / find_if versus for loop

      [color=blue]
      > BAR_VEC::const_ iterator seg_iter = std::find_if(bv .begin(), bv.end(),
      > std::bind1st(Is Id(), id_to_find));
      > if (seg_iter != bv.end()) {
      > std::cout << " found " << id_to_find << std::endl;
      > }
      >
      > IMHO it's prettier if you use std::for_each, but this approach has the
      > more efficient fast failure.[/color]

      I'm reading that function objects with state( whatever that means-
      haven't figured out 'state' yet ) leads to unpredictable results when
      passed to for_each.

      I haven't figured out how to check against bv.end yet but heres what
      I've got thus far:

      std::for_each(b v.begin(), bv.end(), std::bind1st(Is Id(), id_to_find));

      Comment

      • Daniel T.

        #4
        Re: std::find / find_if versus for loop

        In article <1138426882.717 179.152250@g14g 2000cwa.googleg roups.com>,
        "ma740988" <ma740988@gmail .com> wrote:
        [color=blue]
        > Trying to get more acclimated with the use of function objects. As
        > part of my test, consider:
        >
        > # include <vector>
        > # include <iostream>
        > # include <algorithm>
        > #include <stdexcept>
        > #include <bitset>
        >
        > using std::vector;
        > using std::cout;
        > using std::endl;
        > using std::ostream;
        >
        > using std::bitset;
        >
        > class bar {
        > int iden;
        > public:
        > bar(int id) : iden(id) {}
        > int get_id() const { return iden; }
        > };
        > class my_foo {
        > typedef std::vector <bar> BAR_VEC;
        > BAR_VEC bv;
        >
        > public:
        > my_foo()
        > {
        > bv.push_back(ba r(0));
        > bv.push_back(ba r(1));
        > bv.push_back(ba r(3));
        > }
        > void find ( int id_to_find )
        > {
        > BAR_VEC::const_ iterator end = bv.end();
        > for ( BAR_VEC::iterat or it = bv.begin(); it != end; ++it )
        > {
        > if ( id_to_find == it->get_id() )
        > {
        > std::cout << " found " << id_to_find << std::endl;
        > }
        > }
        > // BAR_VEC seg_iter = std::find(
        > // bv.begin(), bv.end(),
        > // XXX ); // XXX now the fancy functor or predicate business - i
        > suppose
        >
        > }
        > };
        >
        >
        > int main()
        > {
        > my_foo m;
        > m.find( 0 ) ;
        > m.find( 1 ) ;
        > m.find( 9 ) ;
        > }
        >
        > Now within the find function. I'd like to use std::find or
        > std::find_if to achieve the same result as the for loop but I'm
        > getting wrapped around the axle trying to 'plug' a parameter/functor
        > into the third argument of find.
        > Again this is pure experiment. Perusing a text here and I'm just
        > trying to create examples as I go along, in an attempt to embrace
        > different views of iterating across containers/ (where necessary ) call
        > member functions etc. beyond the convential for loop.[/color]

        First I'll give the answer, then I'll explain how I got there.

        The answer is:

        void my_foo::find(in t id_to_find) {
        if (find_if(bv.beg in(), bv.end(), compose1(bind2n d(equal_to<int> (),
        id_to_find ), mem_fun_ref( &bar::get_id ) ) ) != bv.end() )
        cout << "found " << id_to_find << "\n";
        }

        Now how did I come up with that answer?

        First just extract the entire guts into a struct:

        struct foo : public unary_function< bar, bool> {
        int id_to_find;
        foo(int i): id_to_find(i) { }
        bool operator()(cons t bar& bar_) const {
        return bar_.get_id() == id_to_find;
        }
        };

        void my_foo::find(in t id_to_find)
        {
        if (find_if(bv.beg in(), bv.end(), foo(id_to_find) ) != bv.end())
        cout << "found " << id_to_find << "\n";
        }

        (Note: I really have to do the above before I can come up with an
        answer, the rest I can usually get without having to actually compile
        each step. In other words, with practice, you should be able to go
        straight from the above to the correct answer.)

        Now we tease out some of the guts into standard functors. Our goal here
        is to end up with a functor that accepts a 'bar' object because that is
        what is in the container.

        The last thing that happens in the 'foo' struct's op() is the
        comparison, so:

        struct foo : public unary_function< bar, bool> {
        int id_to_find;
        foo(int i): id_to_find(i) { }
        bool operator()(cons t bar& bar_) const {
        equal_to<int> a = equal_to<int>() ;
        return a(bar_.get_id() , id_to_find);
        }
        };

        Now we have a functor 'a' that accepts two ints, one of which comes from
        our bar object. Let's remove the second int from it by binding that
        second arg:

        struct foo : public unary_function< bar, bool> {
        int id_to_find;
        foo(int i): id_to_find(i) { }
        bool operator()(cons t bar& bar_) const {
        binder2nd<equal _to<int> > b =
        bind2nd(equal_t o<int>(), id_to_find);
        return b(bar_.get_id() );
        }
        };

        Now we have a functor 'b' that accepts the results of bar::get_id. Let's
        bind that up into a functor as well:

        struct foo : public unary_function< bar, bool> {
        int id_to_find;
        foo(int i): id_to_find(i) { }
        bool operator()(cons t bar& bar_) const {
        binder2nd<equal _to<int> > b =
        bind2nd(equal_t o<int>(), id_to_find);
        const_mem_fun_r ef_t<int, bar> c =
        mem_fun_ref(&ba r::get_id);
        return b(c(bar_));
        }
        };

        Now we have our functor 'c' that accepts a bar object, but it needs to
        pass its results to another functor, and there is nothing in the std
        namespace that can help us. Fortunately, there is an STL functor that
        can do the job. <http://www.sgi.com/tech/stl/unary_compose.h tml>

        struct foo : public unary_function< bar, bool> {
        int id_to_find;
        foo(int i): id_to_find(i) { }
        bool operator()(cons t bar& bar_) const {
        stl::unary_comp ose<binder2nd<e qual_to<int> >,
        const_mem_fun_r ef_t<int, bar> > d =
        compose1(bind2n d(equal_to<int> (), id_to_find),
        mem_fun_ref(&ba r::get_id));
        return d(bar_);
        }
        };

        There we go. The functor 'd' accepts a bar object and returns the
        results we wanted. Just replace the 'foo' functor in the 'my_foo::find'
        function with everything to the left of the 'd =' above.

        Here is that 'unary_compose' and 'compose1' functor and function...

        template <typename Op1, typename Op2>
        class unary_compose:
        public std::unary_func tion<typename Op2::argument_t ype,
        typename Op1::result_typ e>
        {
        Op1 fn1;
        Op2 fn2;
        public:
        unary_compose(c onst Op1& x, const Op2& y): fn1(x), fn2(y) {}
        typename Op1::result_typ e operator()(cons t typename
        Op2::argument_t ype& x) const {
        return fn1(fn2(x));
        }
        };

        template <typename Op1, typename Op2>
        inline unary_compose<O p1, Op2> compose1(const Op1& fn1, const Op2& fn2) {
        return unary_compose<O p1, Op2>(fn1, fn2);
        }

        Comment

        • Nitin Motgi

          #5
          Re: std::find / find_if versus for loop

          cbsmith@gmail.c om wrote:[color=blue]
          > There are different ways to go with this, but I'd go with something
          > like:
          >
          > struct IsId : public std::binary_fun ction<int, bar, bool> {
          > bool operator()(int anId, const bar& aBar) const {
          > return anId == aBar.get_id();
          > }
          > };
          >[/color]

          Can predicate model use the binary_function or should it be only
          unary_function.

          Thank you,
          Nitin Motgi

          Comment

          • Roland Pibinger

            #6
            Re: std::find / find_if versus for loop

            On Sat, 28 Jan 2006 18:37:36 GMT, "Daniel T."
            <postmaster@ear thlink.net> wrote:
            [color=blue]
            >In article <1138426882.717 179.152250@g14g 2000cwa.googleg roups.com>,
            > "ma740988" <ma740988@gmail .com> wrote:
            >[color=green]
            >> void find ( int id_to_find )
            >> {
            >> BAR_VEC::const_ iterator end = bv.end();
            >> for ( BAR_VEC::iterat or it = bv.begin(); it != end; ++it )
            >> {
            >> if ( id_to_find == it->get_id() )
            >> {
            >> std::cout << " found " << id_to_find << std::endl;[/color][/color]
            break;[color=blue][color=green]
            >> }
            >> }[/color]
            >
            >The answer is:
            >
            >void my_foo::find(in t id_to_find) {
            > if (find_if(bv.beg in(), bv.end(), compose1(bind2n d(equal_to<int> (),
            > id_to_find ), mem_fun_ref( &bar::get_id ) ) ) != bv.end() )
            > cout << "found " << id_to_find << "\n";
            >}
            >
            >Now how did I come up with that answer?[/color]

            [dozens of lines with geek-style code snipped]

            You mean, you would really replace a simple for-loop with that? LOL!

            Regards,
            Roland Pibinger

            Comment

            • Daniel T.

              #7
              Re: std::find / find_if versus for loop

              In article <43dbc1af.32622 64@news.utanet. at>,
              rpbg123@yahoo.c om (Roland Pibinger) wrote:
              [color=blue]
              > On Sat, 28 Jan 2006 18:37:36 GMT, "Daniel T."
              > <postmaster@ear thlink.net> wrote:
              >[color=green]
              > >In article <1138426882.717 179.152250@g14g 2000cwa.googleg roups.com>,
              > > "ma740988" <ma740988@gmail .com> wrote:
              > >[color=darkred]
              > >> void find ( int id_to_find )
              > >> {
              > >> BAR_VEC::const_ iterator end = bv.end();
              > >> for ( BAR_VEC::iterat or it = bv.begin(); it != end; ++it )
              > >> {
              > >> if ( id_to_find == it->get_id() )
              > >> {
              > >> std::cout << " found " << id_to_find << std::endl;[/color][/color]
              > break;[color=green][color=darkred]
              > >> }
              > >> }[/color]
              > >
              > >The answer is:
              > >
              > >void my_foo::find(in t id_to_find) {
              > > if (find_if(bv.beg in(), bv.end(), compose1(bind2n d(equal_to<int> (),
              > > id_to_find ), mem_fun_ref( &bar::get_id ) ) ) != bv.end() )
              > > cout << "found " << id_to_find << "\n";
              > >}
              > >
              > >Now how did I come up with that answer?[/color]
              >
              > [dozens of lines with geek-style code snipped]
              >
              > You mean, you would really replace a simple for-loop with that? LOL![/color]

              Not necessarily, as the OP said, it is merely an exorcise.


              --
              Magic depends on tradition and belief. It does not welcome observation,
              nor does it profit by experiment. On the other hand, science is based
              on experience; it is open to correction by observation and experiment.

              Comment

              • ma740988

                #8
                Re: std::find / find_if versus for loop


                Daniel T. wrote:[color=blue]
                > In article <1138426882.717 179.152250@g14g 2000cwa.googleg roups.com>,
                > "ma740988" <ma740988@gmail .com> wrote:
                >[color=green]
                > > Trying to get more acclimated with the use of function objects. As
                > > part of my test, consider:
                > >
                > > # include <vector>
                > > # include <iostream>
                > > # include <algorithm>
                > > #include <stdexcept>
                > > #include <bitset>
                > >
                > > using std::vector;
                > > using std::cout;
                > > using std::endl;
                > > using std::ostream;
                > >
                > > using std::bitset;
                > >
                > > class bar {
                > > int iden;
                > > public:
                > > bar(int id) : iden(id) {}
                > > int get_id() const { return iden; }
                > > };
                > > class my_foo {
                > > typedef std::vector <bar> BAR_VEC;
                > > BAR_VEC bv;
                > >
                > > public:
                > > my_foo()
                > > {
                > > bv.push_back(ba r(0));
                > > bv.push_back(ba r(1));
                > > bv.push_back(ba r(3));
                > > }
                > > void find ( int id_to_find )
                > > {
                > > BAR_VEC::const_ iterator end = bv.end();
                > > for ( BAR_VEC::iterat or it = bv.begin(); it != end; ++it )
                > > {
                > > if ( id_to_find == it->get_id() )
                > > {
                > > std::cout << " found " << id_to_find << std::endl;
                > > }
                > > }
                > > // BAR_VEC seg_iter = std::find(
                > > // bv.begin(), bv.end(),
                > > // XXX ); // XXX now the fancy functor or predicate business - i
                > > suppose
                > >
                > > }
                > > };
                > >
                > >
                > > int main()
                > > {
                > > my_foo m;
                > > m.find( 0 ) ;
                > > m.find( 1 ) ;
                > > m.find( 9 ) ;
                > > }
                > >
                > > Now within the find function. I'd like to use std::find or
                > > std::find_if to achieve the same result as the for loop but I'm
                > > getting wrapped around the axle trying to 'plug' a parameter/functor
                > > into the third argument of find.
                > > Again this is pure experiment. Perusing a text here and I'm just
                > > trying to create examples as I go along, in an attempt to embrace
                > > different views of iterating across containers/ (where necessary ) call
                > > member functions etc. beyond the convential for loop.[/color]
                >
                > First I'll give the answer, then I'll explain how I got there.
                >
                > The answer is:
                >
                > void my_foo::find(in t id_to_find) {
                > if (find_if(bv.beg in(), bv.end(), compose1(bind2n d(equal_to<int> (),
                > id_to_find ), mem_fun_ref( &bar::get_id ) ) ) != bv.end() )
                > cout << "found " << id_to_find << "\n";
                > }
                >[/color]
                I read this and I get depressed. I've got such a loooong (sic) ways to
                go, before I could put that together :) I'm sitting here trying to
                create scenarios for usage on some of these algorithms. Get this:
                make_heap, push_heap, pop_heap, sort_heap. I'm thinking for what
                purpose? Oh, well I'll get back to those in a minute - or just skip
                those all together.

                In any event, thanks for the tip.

                Comment

                • Daniel T.

                  #9
                  Re: std::find / find_if versus for loop

                  In article <1138480257.963 224.187910@g49g 2000cwa.googleg roups.com>,
                  "ma740988" <ma740988@gmail .com> wrote:
                  [color=blue]
                  > Daniel T. wrote:[/color]
                  [color=blue][color=green]
                  > > The answer is:
                  > >
                  > > void my_foo::find(in t id_to_find) {
                  > > if (find_if(bv.beg in(), bv.end(), compose1(bind2n d(equal_to<int> (),
                  > > id_to_find), mem_fun_ref(&ba r::get_id))) != bv.end())
                  > > cout << "found " << id_to_find << "\n";
                  > > }
                  > >[/color]
                  > I read this and I get depressed. I've got such a loooong (sic) ways to
                  > go, before I could put that together :) I'm sitting here trying to
                  > create scenarios for usage on some of these algorithms. Get this:
                  > make_heap, push_heap, pop_heap, sort_heap. I'm thinking for what
                  > purpose? Oh, well I'll get back to those in a minute - or just skip
                  > those all together.
                  >
                  > In any event, thanks for the tip.[/color]

                  From Bjarne Stroustrup, "Is this readable?... The notation is logical,
                  but it does take some getting used to."

                  As others have pointed out, what exactly is wrong with:

                  void my_foo::find( int id_to_find ) {
                  vector<bar>::co nst_iterator end = bv.end();
                  for ( vector<bar>::co nst_iterator it = bv.begin();
                  it != end && it->get_id() != id_to_find; ++it ) { }
                  if ( it != end )
                  cout << "found " << id_to_find << "\n";
                  }

                  After all, that is what my grand find_if/compose1/&c. "functor
                  construct" is doing isn't it?

                  Well, they are both as efficient.

                  Is the for loop easer to read? The functor construct uses words like
                  'find_if' and 'equal_to'. Curiously, the for loop needs to do a != to
                  find an element that is equal to the value we are seeking...

                  Is the for loop easer to write? Initially, the for loop does seem easer,
                  until you look at the condition in it. You better have a strong grasp of
                  operator precedence and will you catch the != bit to find the element
                  that is equal? Sure, for someone who came from a C background and
                  doesn't know the functor library that well, the for loop requires less
                  work to create. However, the whole point of moving from C to C++ (for me
                  at least) was to move to a higher level of abstraction (but still have
                  access to the low-level when needed...)

                  Of course the best solution is probably somewhere in-between, maybe:

                  struct bar_id_eq_to {
                  int id_to_find;
                  bar_id_eq_to(in t i): id_to_find(i) { }
                  bool operator()( const bar& b ) const {
                  return b.get_id() == id_to_find;
                  }
                  };

                  void my_foo::find( int id_to_find ) {
                  if (find_if(bv.beg in(), bv.end(), bar_id_eq_to(id _to_find)) !=
                  bv.end())
                  cout << "found " << id_to_find << "\n";
                  }

                  And finally another quote from Mr. Stroustrup, "A key benefit of the
                  standard library algorithms is that they save the programmer from
                  writing explicit loops. Loops can be tedious and error-prone."

                  You learned that already, your original loop doesn't stop once it finds
                  an element but continues all the way to the end of the loop. But maybe
                  you wanted that behavior from the beginning? Then I would turn to
                  something like:

                  int total = count_if( bv.begin(), bv.end(),
                  compose1(bind2n d(equal_to<int> (), id_to_find),
                  mem_fun_ref(&ba r::get_id)));
                  for ( int i = 0; i < total; ++i )
                  cout << "found " << id_to_find << "\n";


                  or

                  struct output_if_id_is {
                  int id;
                  output_if_id_is ( int i ): id(i) { }
                  void operator()( const bar& b ) const {
                  if ( b.get_id() == id )
                  cout << " found " << id << "\n";
                  }
                  };

                  and

                  for_each( bv.begin(), bv.end(), output_if_id_is ( id_to_find ) );

                  Comment

                  • Daniel T.

                    #10
                    Re: std::find / find_if versus for loop

                    In article <1138456729.366 902.159790@o13g 2000cwo.googleg roups.com>,
                    "ma740988" <ma740988@gmail .com> wrote:
                    [color=blue][color=green]
                    > > BAR_VEC::const_ iterator seg_iter = std::find_if(bv .begin(), bv.end(),
                    > > std::bind1st(Is Id(), id_to_find));
                    > > if (seg_iter != bv.end()) {
                    > > std::cout << " found " << id_to_find << std::endl;
                    > > }
                    > >
                    > > IMHO it's prettier if you use std::for_each, but this approach has the
                    > > more efficient fast failure.[/color]
                    >
                    > I'm reading that function objects with state( whatever that means-
                    > haven't figured out 'state' yet ) leads to unpredictable results when
                    > passed to for_each.[/color]

                    Where are you reading that?

                    --
                    Magic depends on tradition and belief. It does not welcome observation,
                    nor does it profit by experiment. On the other hand, science is based
                    on experience; it is open to correction by observation and experiment.

                    Comment

                    • Roland Pibinger

                      #11
                      Re: std::find / find_if versus for loop

                      On Sat, 28 Jan 2006 20:17:05 GMT, "Daniel T."
                      <postmaster@ear thlink.net> wrote:[color=blue]
                      >In article <43dbc1af.32622 64@news.utanet. at>,
                      > rpbg123@yahoo.c om (Roland Pibinger) wrote:[color=green]
                      >> You mean, you would really replace a simple for-loop with that? LOL![/color]
                      >
                      >Not necessarily, as the OP said, it is merely an exorcise.[/color]

                      Agreed, it exorcises the KISS spirit from the program!
                      ;-)

                      Comment

                      • ma740988

                        #12
                        Re: std::find / find_if versus for loop

                        [color=blue][color=green]
                        > >Not necessarily, as the OP said, it is merely an exorcise.[/color]
                        >
                        > Agreed, it exorcises the KISS spirit from the program!
                        > ;-)[/color]
                        No disrespect, but your comments amount to "no value added" and it that
                        case, there's a saying that some things are better left unsaid.
                        Again, all I'm trying to do is learn how to use some of these
                        algorithms. The frinkin C++ standard is filled with a phletora of
                        algorithms. So I asked myself. Will I ever need 'half' of that mess?
                        The answer is perhaps no but that's irrelevant. I felt a more
                        proactive approach would involve experimenting with some 'test' cases.
                        erase, find and find_if seem like some of the more common ones. After
                        all some containers have their own versions of erase and find. In any
                        event, for experiment, I started to pick on them.

                        I know/am well aware of the simple for loop (I _did_ that) and the need
                        to KISS. I also know that a _fairly competent programmer_ (like most
                        folks on this board- believe me I've scanned the group and seem some
                        code) would perhaps use some combination of algorithms. For instance,
                        my all time favorite. erase an element from a vector. You're almost
                        always going to get some combination of std::erase and std::find. All
                        I'm trying to do is learn those types of things and keep them in my
                        pocket. It's as if I'm given vector's and deque's but I'm still
                        mucking around with C style arrays. Yes, C style arrays have worked
                        _forever_ and will still work but I'm not convinced that's the right
                        attitude to have.

                        An oh!! Didn't one of these authors ( I think it was Bjarne ) mention
                        that for loops can be error prone. I question what's so error prone
                        about the for loop versus the find but maybe I'll find out.

                        Perhaps, I'm taking your comments a tad bit serious, but in the
                        meantime, find somebody else's post to answer.

                        Comment

                        • ma740988

                          #13
                          Re: std::find / find_if versus for loop

                          [color=blue]
                          >
                          > From Bjarne Stroustrup, "Is this readable?... The notation is logical,
                          > but it does take some getting used to."[/color]
                          I'll need to go chase down where he said this but point taken
                          [color=blue]
                          > Sure, for someone who came from a C background and
                          > doesn't know the functor library that well, the for loop requires less
                          > work to create. However, the whole point of moving from C to C++ (for me
                          > at least) was to move to a higher level of abstraction (but still have
                          > access to the low-level when needed...)[/color]
                          Well said.
                          [color=blue]
                          > And finally another quote from Mr. Stroustrup, "A key benefit of the
                          > standard library algorithms is that they save the programmer from
                          > writing explicit loops. Loops can be tedious and error-prone."[/color]
                          I'll buy it but to me, when I first encounted this statement. tedious,
                          Ok!!
                          error-prone. I could easily ruin - say a predicate.

                          [color=blue]
                          > You learned that already, your original loop doesn't stop once it finds
                          > an element but continues all the way to the end of the loop. But maybe
                          > you wanted that behavior from the beginning?[/color]
                          No I didn't. I suspect that's an error-prone scenario
                          [color=blue]
                          > Then I would turn to something like:
                          > int total = count_if( bv.begin(), bv.end(),
                          > compose1(bind2n d(equal_to<int> (), id_to_find),
                          > mem_fun_ref(&ba r::get_id)));
                          > for ( int i = 0; i < total; ++i )
                          > cout << "found " << id_to_find << "\n";
                          >
                          >
                          > or
                          >
                          > struct output_if_id_is {
                          > int id;
                          > output_if_id_is ( int i ): id(i) { }
                          > void operator()( const bar& b ) const {
                          > if ( b.get_id() == id )
                          > cout << " found " << id << "\n";
                          > }
                          > };
                          >
                          > and
                          >
                          > for_each( bv.begin(), bv.end(), output_if_id_is ( id_to_find ) );[/color]

                          Comment

                          • ma740988

                            #14
                            Re: std::find / find_if versus for loop

                            [color=blue]
                            >
                            > You learned that already, your original loop doesn't stop once it finds
                            > an element but continues all the way to the end of the loop. But maybe
                            > you wanted that behavior from the beginning? Then I would turn to
                            > something like:[/color]

                            Actually, here's my test scenario and what I'm trying to do:


                            /*
                            Given a vector of my_struct1 and a vector of my_struct2.
                            I'll compare the vector of my_struct1 with my_struct2 for equality:

                            To do this:
                            Consider
                            my_struct1 (in main below) - told me I should have
                            a segment_id - 5, data_size - 0x100, value - 0xA5.

                            Well, I'll walk through my_struct2.
                            In my_struct2, there's a segment_id - 5, data_size - 0x100.

                            The question then becomes do I have a value of 0xA5 in
                            my_struct2. To determine this.
                            I search the address - ptr_addr in my_struct2 to detemine
                            if the value is 0xA5 for the length of 0x100
                            */

                            # include <vector>
                            # include <iostream>
                            # include <algorithm>
                            #include <fstream>

                            using std::cout;
                            using std::endl;
                            using std::vector;
                            using std::ostream;


                            typedef unsigned int uint_type;
                            struct my_struct1 {
                            uint_type segment_id;
                            uint_type data_size;
                            uint_type value;
                            };

                            typedef unsigned char* ADDR_TYPE;
                            struct my_struct2 {
                            uint_type segment_id;
                            uint_type data_size;
                            ADDR_TYPE ptr_addr;
                            };

                            typedef std::vector<my_ struct1> MS1;
                            typedef std::vector<my_ struct2> MS2;

                            int main()
                            {
                            my_struct1 ms11, ms12;
                            ms11.segment_id = 5;
                            ms11.data_size = 0x100;
                            ms11.value = 0xA5;

                            MS1 m1;
                            m1.push_back(ms 11);

                            ms12.segment_id = 2;
                            ms12.data_size = 0x400;
                            ms12.value = 0xB5;
                            m1.push_back(ms 12);

                            int *ptr_addr1 = new int[0x100];
                            std::fill ( ptr_addr1, ptr_addr1 + 0x100, 0xA5 );

                            my_struct2 ms21, ms22;
                            ms21.segment_id = 5;
                            ms21.data_size = 0x100;
                            ms21.ptr_addr = (ADDR_TYPE)ptr_ addr1;

                            MS2 m2;
                            m2.push_back(ms 21);

                            int *ptr_addr2 = new int[0x400];
                            std::fill ( ptr_addr2, ptr_addr2 + 0x400, 0xB5 );

                            ms22.segment_id = 2;
                            ms22.data_size = 0x400;
                            ms22.ptr_addr = (ADDR_TYPE)ptr_ addr2;

                            m2.push_back(ms 22);
                            delete [] ptr_addr1;
                            delete [] ptr_addr2;
                            }

                            Comment

                            • Daniel T.

                              #15
                              Re: std::find / find_if versus for loop

                              In article <1138541931.138 863.300570@g14g 2000cwa.googleg roups.com>,
                              "ma740988" <ma740988@gmail .com> wrote:
                              [color=blue][color=green]
                              > >
                              > > From Bjarne Stroustrup, "Is this readable?... The notation is logical,
                              > > but it does take some getting used to."[/color]
                              >
                              > I'll need to go chase down where he said this but point taken[/color]

                              Section 18.4.4.1 Binders (page 520 in my edition.)
                              [color=blue][color=green]
                              > > And finally another quote from Mr. Stroustrup, "A key benefit of the
                              > > standard library algorithms is that they save the programmer from
                              > > writing explicit loops. Loops can be tedious and error-prone."[/color]
                              > I'll buy it but to me, when I first encounted this statement. tedious,
                              >
                              > Ok!!
                              > error-prone. I could easily ruin - say a predicate.[/color]

                              Not likely. :-) *If* you get it to compile, it will probably be right.
                              Unlike the loop which will probably compile the first time, but is more
                              likely to produce the wrong answer, (or worse the right answer but it
                              has some other subtle bug that doesn't show up for a while, like your
                              original loop.)


                              --
                              Magic depends on tradition and belief. It does not welcome observation,
                              nor does it profit by experiment. On the other hand, science is based
                              on experience; it is open to correction by observation and experiment.

                              Comment

                              Working...