Lambda的实际用途示例

时间:2017-11-06 10:53:26

标签: c++ lambda

我最近开始研究lambdas供个人使用。我已经编写了几年了,我已经发布了多种产品,但是,我从未发现自己需要使用lambdas。我已经阅读了各种lambda问题的其他堆栈交换答案,但是我没有找到一个解释,它显示了一个非常简单的例子,它真正推动了lambdas是必要的(在某些情况下)。在做了一些研究后,我不相信lambdas的某些特定用法不能用标准函数实现,但是,这并不意味着太多,因为我的主题范围非常有限。

有人可以为lambda提供一个相当简单的用例,演示它们如何比典型函数更强大(在正确的情况下)?

3 个答案:

答案 0 :(得分:15)

C ++在C ++ 11之前很久就完成了图灵。兰布达不是为了让一些不可能成为可能的东西。没有它们你可以做很多事情。 它们可以简化某些代码。

例如,允许动态创建标准算法库的仿函数。当然你可以自己定义一个。但这需要超出你的功能,并命名一个新类型。一个简单的std::transform调用的大量样板文件,作为一个例子。

它们保持代码本地化,不需要您污染任何名称,并且一旦掌握它就很容易使用。

作为奖励,在his talk about functional C++中,Kevlin Henney将一个示例函数从一个框架简化为一个真正叫出“使用lambda”的东西。所以从他的演讲中借一点,考虑一下命令注册功能:

void register_command(std::string cmdName, std::function<void()> f);

您想要注册一个只打开灯泡的命令。与以下相比,您需要为自定义仿函数编写多少样板文件?

register_command("Turn On Light-bulb", [&light_controller]() {
  light_controller.on();
});

请注意,以及您个人宁愿维护的代码库。

答案 1 :(得分:4)

现在可以用lambda完成的所有事情都可以在C ++ 03中通过手写struct / class并重载operator() 来完成(通常称为&# 34;函子&#34)。这有一个很大的问题:缺乏简洁性缺乏地方性

想象一下,将模板化的谓词传递给C ++ 03中的std::find_if

struct predicate
{
    template <typename T>
    bool operator()(const T& x) { return boop(x); }
};

void foo()
{
    something(std::find_if(c.begin(), c.end(), predicate()));
}

你需要:

  • 在某处定义predicate,可能远离其使用的位置。

  • 拥有structoperator()重载的样板。

  • 在阅读源代码时跳转,了解predicate正在做什么。

将它与C ++ 14通用lambda进行比较:

void foo()
{
    something(std::find_if(c.begin(), c.end(), 
        [](const auto& x){ return boop(x); });
}

动臂。一切都在那里,本地,最小的样板。

Lambda不是魔术。他们纯粹是语法糖。但我认为,他们将手语struct s&#34; 作为&#34; &#34;语法糖,C ++是语法糖到C&#34;

它们改变了编写代码的方式,它们使函数范例(例如高阶函数)可行,并且可以使代码更强大,更安全。

答案 2 :(得分:2)

我们可以在不使用lambdas的情况下做几乎所有事情。但是,引入lambda用于支持函数式编程,并且在许多情况下是有用的。

我最近在线程中使用它,这让我的生活更轻松。这是一个非常简化的版本

int main() {
    int value = 0;

    thread th { [=](){ 
        cout<<"I am inside thread fn Value = "<<value<<endl;
    }};

    th.join();
}

这里有两个明显的好处

  1. lambda阻止创建全局或类静态函数
  2. 我不需要将参数传递给线程(这是一件很复杂的事情),因为lambda闭包会解决这个问题。
  3. 因此,很少有情况下lambda可能是更好的选择,但它并不意味着我们不能对函数做同样的事情