Before C++11 I used boost::bind
or boost::lambda
a lot. The bind
part made it into the standard library (std::bind
) the other part became part of the core language (C++ lambdas) and made the use of lambdas a lot easier. Nowadays, I hardly use std::bind
, since I can do almost anything with C++ lambdas. There's one valid use-case for std::bind
that I can think of:
struct foo
{
template < typename A, typename B >
void operator()(A a, B b)
{
cout << a << ' ' << b;
}
};
auto f = bind(foo(), _1, _2);
f( "test", 1.2f ); // will print "test 1.2"
The C++14 equivalent for that would be
auto f = []( auto a, auto b ){ cout << a << ' ' << b; }
f( "test", 1.2f ); // will print "test 1.2"
Much shorter and more concise. (In C++11 this does not work yet because of the auto parameters.) Is there any other valid use case for std::bind
beating the C++ lambdas alternative or is std::bind
superfluous with C++14?
For me, a valid use for
std::bind
is to make it clear that I'm using a member function as a predicate. That is, if all I do is call a member function, it's bind. If I do extra stuff with the argument (besides calling a memeber function), it's a lambda:Scott Meyers gave a talk about this. This is what I remember:
In C++14 there is nothing useful bind can do that can't also be done with lambdas.
In C++11 however there are some things that can't be done with lambdas:
You can't move the variables while capturing when creating the lambdas. Variables are always captured as lvalues. For bind you can write:
Expressions can't be captured, only identifiers can. For bind you can write:
Overloading arguments for function objects. This was already mentioned in the question.
In C++14 all of these possible.
Move example:
Expression example:
See question
Perfect forwarding: You can write
Some disadvantages of bind:
Bind binds by name and as a result if you have multiple functions with the same name (overloaded functions) bind doesn't know which one to use. The following example won't compile, while lambdas wouldn't have a problem with it:
On the other hand lambdas might theoretically generate more template code than bind. Since for each lambda you get a unique type. For bind it is only when you have different argument types and a different function (I guess that in practice however it doesn't happen very often that you bind several time with the same arguments and function).
What Jonathan Wakely mentioned in his answer is actually one more reason not to use bind. I can't see why you would want to silently ignore arguments.
Sometimes it is just less code. Consider this:
Then
vs lambda
I think that bind is easier to read here compared to the lambda which looks like a https://en.wikipedia.org/wiki/Brainfuck
Just expanding @BertR's comment to this answer to something testable, though I confess I couldn't quite get a solution using std::forward<> to work.
Test at Compiler Explorer
std::bind
can still do one thing polymorphic lambdas can't: invoke overloaded functionsThe call wrapper created by the bind expression calls different functions depending on the arguments you give it, the closure from a C++14 polymorphic lambda can take different types of arguments but can't take a different number of arguments, and always invokes (specializations of) the same function on the closure. Correction: see the comments below
The wrapper returned by
std::bind
can also be called with too many arguments and it will ignore them, whereas a closure created by a lambda will diagnose attempts to pass too many arguments ... but I don't consider that a benefit ofstd::bind
:)Another difference is that arguments to bind must be copied or moved, while a lambda can use variables captured by reference. See example below:
Not sure if it's possible to workaround the issue to use bind above without changing the signature of
void p(const int&)
.