I have a foo
which is a std::vector
. It represents the \"edge\" values for a set of ranges.
For example, if foo
is
What about going straight from Stone Age (bind2nd
) to the Iron Age with a C++14 generic lambda, bypassing the Bronze Age (bind
)?
std::find_if(foo.begin(), foo.end(), [&](auto const& elem) {
return elem > bar;
});
And if the input is sorted
std::lower_bound(foo.begin(), foo.end(), bar);
Lambdas read much easier and are also easier to inline than std::bind
expresions. See e.g. Lavevej's CppCon 2015 talk.
In C++11, you can use std::bind
; it just isn't as obvious how to use it:
#include <functional>
using namespace std::placeholders;
std::find_if(
foo.begin(),
foo.end(),
// create a unary function object that invokes greater<int>::operator()
// with the single parameter passed as the first argument and `bar`
// passed as the second argument
std::bind(std::greater<int>(), _1, bar)
) - foo().begin() - 1;
The key is the use of the placeholder argument, which are declared in the std::placeholders
namespace. std::bind
returns a function object that takes some number of parameters when it is invoked. The placeholders used inside the call to std::bind
show how the arguments provided when the resulting object is invoked map to the argument list to the callable that you're binding to. So, for instance:
auto op1 = std::bind(std::greater<int>(), _1, bar);
op1(5); // equivalent to std::greater<int>()(5, bar)
auto op2 = std::bind(std::greater<int>(), bar, _1);
op2(5); // equivalent to std::greater<int>()(bar, 5)
auto op3 = std::bind(std::greater<int>(), _2, _1);
op3(5, bar); // equivalent to std::greater<int>()(bar, 5)
auto op4 = std::bind(std::greater<int>(), _1, _2);
op4(5, bar); // equivalent to std::greater<int>()(5, bar)
bind
version would be:
bind(std::greater<int>(), placeholders::_1, bar)
but I think, it is more encouraged to use lambdas, as in:
[bar](const int a){return bar < a;}
It is also encouraged to use overloaded functions begin/end
instead of method calls. so it would be like:
find_if(begin(foo), end(foo), [bar](const int a){return bar < a;})