绑定与 Lambda?

我有一个关于首选哪种样式的问题:C++0x 中的 std::bind Vs lambda.我知道它们以某种方式服务于不同的目的,但让我们举一个交叉功能的例子.

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.

使用lambda:

uniform_int<> distribution(1, 6);
mt19937 engine;
// lambda style
auto dice = [&]() { return distribution(engine); };

使用绑定:

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?

推荐答案

正如您所说,bind 和 lambdas 的目标并不完全相同.

As you said, bind and lambdas don't quite exactly aim at the same goal.

例如,对于使用和编写 STL 算法,恕我直言,lambda 显然是赢家.

For instance, for using and composing STL algorithms, lambdas are clear winners, IMHO.

为了说明,我记得一个非常有趣的答案,这里是关于堆栈溢出的,有人询问十六进制幻数的想法,(如 0xDEADBEEF、0xCAFEBABE、0xDEADDEAD 等)并被告知如果他是一个真正的 C++ 程序员,他只需下载英文单词列表并使用简单的单行 C++ :)

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, "
"),
        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
    );
}

这个片段,在纯 C++98 中,打开英文单词文件,扫描每个单词并只打印长度为 8 的带有 'a', 'b', 'c', 'd', 'e' 或'f' 字母.

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.

现在,打开 C++0X 和 lambda :

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, "
"),
    [](const std::string& s)
    {
       return (s.size() == 8 && 
               s.find_first_not_of("abcdef") == std::string::npos);
    }
 );
}

这个读起来还是有点繁重(主要是istream_iterator的业务),但是比bind版本简单很多:)

This is still a bit heavy to read (mainly because of the istream_iterator business), but a lot simpler than the bind version :)

相关文章