hamishmcn
hamishmcn

Reputation: 7981

Trying to use boost lambda, but my code won't compile

I am trying to use boost lambda to avoid having to write trivial functors. For example, I want to use the lambda to access a member of a struct or call a method of a class, eg:

#include <vector>
#include <utility>
#include <algorithm>
#include <boost/lambda/lambda.hpp>

using namespace std;
using namespace boost::lambda;

vector< pair<int,int> > vp;

vp.push_back( make_pair<int,int>(1,1) );
vp.push_back( make_pair<int,int>(3,2) );
vp.push_back( make_pair<int,int>(2,3) );

sort(vp.begin(), vp.end(), _1.first > _2.first );

When I try and compile this I get the following errors:

error C2039: 'first' : is not a member of 'boost::lambda::lambda_functor<T>'
        with
        [
            T=boost::lambda::placeholder<1>
        ]
error C2039: 'first' : is not a member of 'boost::lambda::lambda_functor<T>'
        with
        [
            T=boost::lambda::placeholder<2>
        ]

Since vp contains pair<int,int> I thought that _1.first should work. What I am doing wrong?

Upvotes: 2

Views: 2914

Answers (2)

rlbond
rlbond

Reputation: 67739

According to this, I believe the syntax is

sort(vp.begin(), vp.end(), 
bind(&pair<int,int>::first, _1) > bind(&pair<int,int>::first, _2));

However, I'd like to point out the (not so?) obvious -- sort(vp.begin(), vp.end()); will basically do the same thing. pairs are by default sorted by their first argument, then by the second. Since you're using sort (which is not stable), you're going to have all the pairs sorted by first, and then the pairs with equal first are going to be in more or less random order.

If you want to preserve the order when the first elements are equal, you should use stable_sort instead.

Upvotes: 4

GManNickG
GManNickG

Reputation: 503745

What you want is something akin to:

#include <boost/lambda/bind.hpp> // new header

// typedefs make code easier
typedef pair<int,int> pair_type;
typedef vector<pair_type> vector_type;

vector_type vp;

vp.push_back( make_pair(1,1) ); // don't specify template arguments!
vp.push_back( make_pair(3,2) ); // the entire point of make_pair is
vp.push_back( make_pair(2,3) ); // to deduce them.

sort(vp.begin(), vp.end(),
        bind(&pair_type::first, _1) > bind(&pair_type::first, _2) );

Upvotes: 7

Related Questions