Search code examples
c++templatesboostboost-lambda

problems with C++ boost lambda and ==-operator


There is:

template<typename T>
bool any(::Ref<Iterator<T> > i, boost::function<bool(T)> pred) {
    // ...
}

And:

template<typename T> struct Ref {
     // ...
};

template<typename T> struct Iterator {
     // ...
};

Then I have this call (which errors):

int forworm = 42;
bool x = any<CWorm*>(worms(), (_1 ->* &CWorm::getID) == forworm)

And worms() returns a Ref<Iterator<CWorm*> Ref> and there is int CWorm::getID(); (which is a member function).

This fails with a very lengthy error about invalid operands to binary expression. Part of it:

/usr/local/include/boost/lambda/detail/operator_lambda_func_base.hpp:222:1:{222:1-222:63}{222:1-222:63}: error: invalid operands to binary expression ('typename lambda_functor_base >, tuple >, int (CWorm::*const)() const, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type> >::sig >::type' (aka 'member_pointer_caller') and 'int') [3]

Why?

How can I fix it?

If I do it somewhat more verbose, i.e. not via lambdas but I declare another function manually and use boost::bind, it works. I.e. like this:

static bool _wormIdEqual(CWorm* w, int wormId) {
    return w->getID() == wormId;
}

any<CWorm*>(worms(), boost::bind(_wormIdEqual, _1, forworm)))

Solution

  • You should be able to do this:

    #include <boost/lambda/bind.hpp>
    
    using boost::lambda::bind;
    bool x = any<CWorm*>(worms(), bind(&CWorm::getID, _1) == forworm);
    

    The boost::lambda::bind(&CWorm::getID, _1) behaves just as you hoped (_1 ->* &CWorm::getID) would, and can (lazily) compare for equality against forworm. So it's still very much a lambda function.