6

I was reading a StackOverFlow post regarding sorting a vector of pairs by the second element of the pair. The most obvious answer was to create a predicate, but one answer that used boost caught my eye.

std::sort(a.begin(), a.end(), 
  boost::bind(&std::pair<int, int>::second, _1) <
  boost::bind(&std::pair<int, int>::second, _2));

I've been trying to figure out how boost::bind works, or at least just how to use it, but I can't figure out what the purpose of the placeholder arguments _1 and _2 are, and the boost documentation doesn't sink in at all.

Could anyone explain this specific usage of boost::bind?

P.S. Original question: How do I sort a vector of pairs based on the second element of the pair?

Community
  • 1
  • 1
Anonymous
  • 4,167
  • 11
  • 47
  • 52

2 Answers2

7

This expression:

boost::bind(&std::pair<int, int>::second, _1) <
boost::bind(&std::pair<int, int>::second, _2)

namely, the use of the < operator actually defines a functor between two other functors, both of which defined by bind.

The functor expected by sort needs to have an operator() which looks like this:

bool operator()(const T& arg1, const T& arg2);

when you're creating a functor using boost's < then the name holders _1 and _2 correspond to arg1 and arg2 of the functor you're creating.

The bind call create a functor that calls ::second of arg1 and arg2

With any luck, the introduction of lambdas in C++0x will make expressions like this obsolete.

shoosh
  • 76,898
  • 55
  • 205
  • 325
  • For the record: `typedef std::pair pair_type; std::sort(a.begin(), a.end(), [](pair_type x, pair_type y){ return x.second < y.second; });` – GManNickG Jan 23 '10 at 03:44
5

std::sort requires a binary predicate to compare two items from the range. The placeholders show where the first and the second argument are going to be used.

boost::bind makes it so that the entire expression reads as _1.second < _2.second (except since the . operator is not overloadable, such expressiveness cannot be achieved).

Both bind calls, in this case, create a function object that accepts a pair<int, int> and returns the value of second. operator< in turn is overloaded to return another binary functor that compares the results of the previous functors. And that gets used by std::sort.

UncleBens
  • 40,819
  • 6
  • 57
  • 90