Bind Vs Lambda?
Solution 1:
C++0x lambdas are monomorphic, while bind can be polymorphic. You cannot have something like
auto f = [](auto a, auto b) { cout << a << ' ' << b; }
f("test", 1.2f);
a and b must have known types. On the other hand, tr1/boost/phoenix/lambda bind allows you to do this:
struct foo
{
typedef void result_type;
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"
Note that the types A and B are not fixed here. Only when f is actually used these two will be deduced.
Solution 2:
As you said, bind and lambdas don't quite exactly aim at the same goal.
For instance, for using and composing STL algorithms, lambdas are clear winners, IMHO.
To illustrate, I remember a really funny answer, here on stack overflow, where someone asked for ideas of hex magic numbers, (like 0xDEADBEEF, 0xCAFEBABE, 0xDEADDEAD etc.) and was told that if he were a real C++ programmer he would simply have download a list of English words and use a simple one-liner of C++ :)
#include <iterator>
#include <string>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
int main()
{
using namespace boost::lambda;
std::ifstream ifs("wordsEn.txt");
std::remove_copy_if(
std::istream_iterator<std::string>(ifs),
std::istream_iterator<std::string>(),
std::ostream_iterator<std::string>(std::cout, "\n"),
bind(&std::string::size, _1) != 8u
||
bind(
static_cast<std::string::size_type (std::string::*)(const char*, std::string::size_type) const>(
&std::string::find_first_not_of
),
_1,
"abcdef",
0u
) != std::string::npos
);
}
This snippet, in pure C++98, open the English words file, scan each word and print only those of length 8 with 'a', 'b', 'c', 'd', 'e' or 'f' letters.
Now, turn on C++0X and lambda :
#include <iterator>
#include <string>
#include <algorithm>
#include <iostream>
#include <fstream>
int main()
{
std::ifstream ifs("wordsEn.txt");
std::copy_if(
std::istream_iterator<std::string>(ifs),
std::istream_iterator<std::string>(),
std::ostream_iterator<std::string>(std::cout, "\n"),
[](const std::string& s)
{
return (s.size() == 8 &&
s.find_first_not_of("abcdef") == std::string::npos);
}
);
}
This is still a bit heavy to read (mainly because of the istream_iterator business), but a lot simpler than the bind version :)
Solution 3:
The C++ 0x lamdba syntax is more readable than the bind syntax. Once you get into more than 2-3 level bind, you code becomes pretty much unreadable and difficult to maintain. I would prefer the more intuitive lambda syntax.
Solution 4:
One of the benefits of lambdas is they are way more useful when you need to add a little big of logic on top of an existing function.
With bind, you are forced to create a new function/method/functor even if the logic is only ever needed in this one place. You need to come up with an appropriate name and it can make the code less understandable as it potentially makes you split up related logic.
With lambda, you can add the new logic inside the lambda (but are not forced to if it makes sense to create a new callable).
Solution 5:
I think it's more a matter of taste. People that quickly grasp new technologies, or are familiar with functional programming will probably prefer lambda syntax, while more conservative programmers will definitively prefer bind, as it is more in par with the traditional C++ syntax.
Such a decision should be made in coordination with the people that will be working with the code, probably through a majority vote.
Which doesn't change the fact however, that lambda syntax is much more powerful and cleaner.