views:

295

answers:

1

I am trying to lean boost::bind, boost::lambda libraries and how they can be used with STL algorithms. Suppose I have vector of int-string pairs which is sorted by int key. Then a place to insert a new pair while keeping the vector sorted can be found as follows:

std::vector<std::pair<int, string> > entries;
...
int k = ...;

// Let's ignore std::lower_bound return value for now
std::lower_bound (entries.begin(), entries.end(), k, 
                  boost::bind (&std::pair<int, string>::first, _1) < k)

Now I would like to replace operator< with a function object (of type std::less<int> in this example):

std::less<int> comparator;

How do I change the code above so it works? I cannot just do

std::lower_bound (entries.begin(), entries.end(), k, 
                  comparator (boost::bind (&std::pair<int, string>::first, _1), k))

because std::less<int>::operator() does not accept whatever is the return type of boost::bind. What am I missing here? TIA

+2  A: 

All you're missing is another bind (and the template parameters on pair):

std::lower_bound(entries.begin(), entries.end(), k, 
                 boost::bind(comparator,
                             boost::bind(&std::pair<int, string>::first, _1),
                             k))

You don't have to do that on the less-than operator in your original code because Boost.Bind provides overloads for that operator that know how to handle the return type of boost::bind.

Rob Kennedy
So the outer boost::bind does the magic of making comparator.operator() accept whatever the inner boost::bind produces. Thanks! (BTW the missing pair template parameters is just an editing error of mine)
Laurynas Biveinis
I was tempted to do this so many times. But when you step back you realize that your code is very hard to read. And now that bind is a part of C++ standard you should note that only boost implementation overloads relational and logical operators.
Nikola Smiljanić