Search code examples
c++boostshared-ptrboost-bind

Using find_if and boost::bind with a set of shared_pointers


I have a vector of shared_ptr, I want to combine boost shared_ptr and bind together.

My question is very similar to this, except that instead of "&MyClass::ReferenceFn" I would like to call "&Element::Fn".

Here is a similar piece of code:

typedef boost::shared_ptr< Vertex > vertex_ptr; 
std::set<vertex_ptr> vertices;

void B::convert()
{
...
if( std::find_if(boost::make_indirect_iterator(vertices.begin()), 
                 boost::make_indirect_iterator(vertices.end() ),  boost::bind( &Vertex::id, boost::ref(*this), _1 ) == (*it)->id() ) == vertices.end() )
}

here is the error:

no matching function for call to ‘bind(<unresolved overloaded function type>, const boost::reference_wrapper<B>, boost::arg<1>&)’

NOTE: I am limited to use the C++03.


Solution

  • To call a member function for each object stored in a collection, you need to use a placeholder as the first bound argument of the boost::bind:

    boost::bind(&Vertex::id, _1) == (*it)->id())
    //                       ~^~
    

    This way, each argument a, will be bound to a member function pointer, and called as (a.*&Vertex::id)().

    However, seeing that the error message says unresolved overloaded function type, it draws a conclusion that your class Vertex can have multiple overloads of member function id. As such, the compiler is unable to tell which one it should pass as the argument of boost::bind. To solve this, use an explicit cast to a member function pointer (the asterisk after colon indicates it's a pointer to a member):

    boost::bind(static_cast<int(Vertex::*)()const>(&Vertex::id), _1) == (*it)->id())
    //                      ~~~~~~~~~~~~~~~~~~~~^
    

    In the case class Vertex has multiple overloads, say:

    int id() const { return 0; }
    void id(int i) { }
    

    you will use the first one for binding.