Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Help understanding boost::bind placeholder arguments

Tags:

c++

boost

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?

like image 694
Anonymous Avatar asked Jan 22 '10 21:01

Anonymous


People also ask

What does boost :: bind do?

boost::bind is a generalization of the standard functions std::bind1st and std::bind2nd. It supports arbitrary function objects, functions, function pointers, and member function pointers, and is able to bind any argument to a specific value or route input arguments into arbitrary positions.

What is _1 in boost :: bind?

_1 is a placeholder. Boost. Bind defines placeholders from _1 to _9 . These placeholders tell boost::bind() to return a function object that expects as many parameters as the placeholder with the greatest number.

Why is it important to bind a function to its arguments C++?

Bind function with the help of placeholders helps to manipulate the position and number of values to be used by the function and modifies the function according to the desired output.

What is std :: placeholder?

The std::placeholders namespace contains the placeholder objects [_1, ..., _N] where N is an implementation defined maximum number.


2 Answers

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.

like image 182
shoosh Avatar answered Nov 15 '22 00:11

shoosh


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.

like image 38
UncleBens Avatar answered Nov 14 '22 23:11

UncleBens