I have a question about which style is preferred: std::bind Vs lambda in C++0x. I know that they serve -somehow- different purposes but lets take an example of intersecting functionality.
Using lambda
:
uniform_int<> distribution(1, 6);
mt19937 engine;
// lambda style
auto dice = [&]() { return distribution(engine); };
Using bind
:
uniform_int<> distribution(1, 6);
mt19937 engine;
// bind style
auto dice = bind(distribution, engine);
Which one should we prefer? why? assuming more complex situations compared to the mentioned example. i.e. What are the advantages/disadvantages of one over the other?
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 :)