c++boostboost-lambda

expressing _1.second->pair().first == r in boost::lambda


I've an expression that I need to put in std::transform as callback, but I don't want to write another method for it. I want to express the expression _1.second->pair().first == r to boost::lambda assuming _1 is the only argument passed to it of type std::pair

I've a generic shorthand functors util::shorthand::pair_second and util::shorthand::pair_first which returns second and first item of a pair.

I can do boost::bind(util::shorthand::pair_second, _1) but then do what ? how to implement rest of the expression ?

-1.second is templated of type Connection<T>.I cannot use C++11


Solution

  • Take a look at Boost.Lambda bind expressions. You can use them to bind member functions and member data.

    I don't have enough information as to the types that you are using, but something like this should work:

    bind(&std::pair<S, R>::first,
         bind(&Connection<T>::pair,
              bind(&std::pair<U, Connection<T> >::second, _1))) == r
    

    Note: The bind in this sample is the one in the boost::lambda namespace, not Boost.Bind.

    EDIT: Complete, compilable example:

    #include <algorithm>
    #include <iostream>
    #include <utility>
    #include <vector>
    
    #include <boost/lambda/lambda.hpp>
    #include <boost/lambda/bind.hpp>
    
    // http://stackoverflow.com/questions/12026884/expressing-1-second-pair-first-r-in-boostlambda/
    
    typedef int S;
    typedef int R;
    
    template <typename T>
    struct Connection
    {
        std::pair<S, R> pair() const {
            return std::make_pair(0, 0);
        }
    };
    
    int main()
    {
        using namespace boost::lambda;
    
        typedef int T;
        typedef int U;
    
        std::vector<std::pair<U, Connection<T> > > vec;
        vec.push_back(std::make_pair(3, Connection<T>()));
        std::vector<bool> res(vec.size());
    
        int r = 0;
        std::transform(vec.begin(), vec.end(), res.begin(),
            bind(&std::pair<S, R>::first,
                bind(&Connection<T>::pair,
                    bind(&std::pair<U, Connection<T> >::second, _1))) == r);
    
        std::vector<bool>::iterator it, end = res.end();
        for (it = res.begin(); it != end; ++it) {
            std::cout << ' ' << *it;
        }
        std::cout << std::endl;
    }