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?
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.
_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.
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.
The std::placeholders namespace contains the placeholder objects [_1, ..., _N] where N is an implementation defined maximum number.
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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With