Boost logo

Boost Users :

From: Forever Kid (foreverkid3_at_[hidden])
Date: 2007-03-29 14:15:49


I was able to answer my own question after some additional reading.

This:

find_if(a_vector.begin(), a_vector.end(),
    bind(equal_to<string>(),bind(&dref,_1),string("with ")));

is equivalent to: (?)

find_if(a_vector.begin(), a_vector.end(),
    (bind(&dref, _1) == string("with ")));

Please correct me if I am missing anything. There's a steep learning curve and I'm still on it.

Thanks,
Graham

----- Original Message ----
From: Forever Kid <foreverkid3_at_[hidden]>
To: boost-users_at_[hidden]
Sent: Thursday, March 29, 2007 11:30:03 AM
Subject: boost::bind syntax with a vector of shared_ptrs and find_if usage

What is the syntax for the line below without using bind's overloaded '==' operator and instead using equal_to<>?

an_iterator = find_if(a_vector.begin(), a_vector.end(),
                (bind(&dref, _1) == string("with ")));

I am doing these as exercises in an attempt to wrap my head around boost::bind.

What has me puzzled, at the moment, is how find_if 'knows' (above) to automatically compare what the share_ptrs are pointing to (the strings). Doesn't a_vector.begin() return an iterator to a shared_ptr and not a string?

Thanks again,
Graham

Current working example:

const string& dref(const shared_ptr<string> &sp)
{
    return *sp;
}

int main (int argc, char *argv[])
{
    vector<shared_ptr<string> > a_vector;

    shared_ptr<string> sp1(new string("Play "));
    shared_ptr<string> sp2(new string("with "));
    shared_ptr<string> sp3(new string("C++!"));

    a_vector.push_back(sp1);
    a_vector.push_back(sp2);
    a_vector.push_back(sp3);

    vector<shared_ptr<string> >::iterator an_iterator;

    an_iterator = find_if(a_vector.begin(), a_vector.end(),
                (bind(&dref, _1) == string("with ")));

    if (an_iterator != a_vector.end())
    {
        shared_ptr<string> sp(*an_iterator);

        cout << "Found " << *sp << endl;
    }
    return 0;
}

----- Original Message ----
From: Jeff F <TriumphSprint2000_at_[hidden]>
To: boost-users_at_[hidden]
Sent: Thursday, March 29, 2007 8:11:56 AM
Subject: Re: [Boost-users] boost::bind syntax with a vector of weak_ptrs

Forever Kid wrote:
> What is the correct boost::bind syntax to use with a standard
> algorithm such as find_if with an array of weak_ptrs or shared_ptrs
> to an object such as a string?
>
> My weak attempt to figure this out is below:
>
> shared_ptr<string> sp1(new string("Play "));
> shared_ptr<string> sp2(new string("with "));
> shared_ptr<string> sp3(new string("C++!"));
>
> vector<weak_ptr<string> > a_vector;
>
> a_vector.push_back(weak_ptr<string>(sp1));
> a_vector.push_back(weak_ptr<string>(sp2));
> a_vector.push_back(weak_ptr<string>(sp3));
>
> // What is the correct syntax here?
> find_if(a_vector.begin(), a_vector.end(), (bind(&equal_to<string>(),
> _1))(string("Play "));

The above has many problems unrelated to weak_ptrs.

(bind(&equal_to<string>(),_1))(string("Play "));
|----------------------------||---------------|
              a b

Part "a" above is not a properly formed bind expression:

    1 - you are passing the address of an equal_to<...> instance.
    2 - equal_to<...> expects two arguments you supply one.

Part "b" attempts to invoke the function object resulting from Part "a", and
passes the result(if part "a" were well formed); a bool to find_if. find_if
then tries to apply operator() to the bool, which again is ill formed.

The proper bind expression for comparing a string _value_ is:

    bind( equal_to<string>(), _1, string("Play ") )

To use this you'd need an indirect or transform iterator adaptor that derefs
the weak ptrs. See

http://www.boost.org/libs/iterator/doc/indirect_iterator.html
http://www.boost.org/libs/iterator/doc/transform_iterator.html

I'm not sure of the details in using an indirect iterator with weak_ptr. A
transform iterator would require you to provide a deref function, and use it
with the iterator adaptor library. This is untested code:

std::string deref_wps( weak_ptr<string> wps ){ return /* derefed wps */; }

    find_if( make_transform_iterator(a_vector.begin(),&deref_wps)
           , make_transform_iterator(a_vector. end(),&deref_wps)
           , bind( equal_to<string>(), _1, string("Play ") )
           );

Or using some of the nice operator overloading provided by bind, you can
forego the iterator adaptors:

    find_if( a_vector.begin()
           , a_vector. end()
           , bind( &deref_wps, _1 ) == string("Play ")
           );

Jeff

_______________________________________________
Boost-users mailing list
Boost-users_at_[hidden]
http://lists.boost.org/mailman/listinfo.cgi/boost-users

 
____________________________________________________________________________________
Looking for earth-friendly autos?
Browse Top Cars by "Green Rating" at Yahoo! Autos' Green Center.
http://autos.yahoo.com/green_center/

 
____________________________________________________________________________________
Be a PS3 game guru.
Get your game face on with the latest PS3 news and previews at Yahoo! Games.
http://videogames.yahoo.com/platform?platform=120121


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net