【问题标题】:Example of a Practical Use for Lambdas [duplicate]Lambda 的实际使用示例
【发布时间】:2018-04-18 12:23:03
【问题描述】:

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

谁能提供一个相当简单的 lambdas 用例来演示它们如何比典型函数更强大(在正确的情况下)?

【问题讨论】:

  • 您不能使用函数来替代捕获 lambda,但您可以structs 与适当的operator() 一起使用。只是该结构由 90% 不必要的样板组成,您可以使用 lambda 跳过这些样板。
  • 我曾经用它来对一些自定义数据类型的向量进行排序,所以我只定义了一个 lambda 函数。但我刚刚意识到我也可以使用std::greater。所以我也很想看看答案
  • “更强大”是什么意思?恕我直言,lambdas 只是一个工具。如果没有理由使用它,请不要使用它。
  • @megabyte1024- 好吧,我特别提到“更强大......(在正确的情况下)。类似于在某些情况下向量比数组更强大,而在其他情况下数组比向量更强大。我特意询问了 lambda 占上风的情况,但是,根据目前的答案,我的措辞可能不适用。
  • 关于函子,this question 非常彻底地回答了您的问题,并且从 C++11 开始,lambdas 现在适合大多数用例

标签: c++ lambda


【解决方案1】:

C++ 早在 C++11 之前就已经完成了图灵。 Lambda 并不是为了让不可能的事情变成可能。没有他们你可以完成很多事情。 它们的存在是为了简化某些代码。

例如,允许即时创建标准算法库的函子。当然,您可以自己定义一个。但这需要超越你的功能,并命名一个新类型。例如,简单调用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();
});

考虑一下,您个人更愿意维护哪个代码库。

【讨论】:

    【解决方案2】:

    现在可以用 lambdas 完成的所有事情都可以在 C++03 中通过用重载的 operator() 手写 struct/class 来完成(通常称为“函子”) .这样做有一个大问题:缺乏简洁性缺乏局部性

    想象一下在 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 不是魔法。它们纯粹是语法糖。但我认为,它们是“手写structs 的语法糖”,因为“C++ 是C 的语法糖”

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

    【讨论】:

    • structs 在 C++ 中并不是真正的东西。另外,您听起来好像必须使用 struct 关键字。
    • @juanchopanza: struct 是一个东西——它相当于class,除了它默认是public。这通常是 C++03 中简单的“类 lambda”函数对象的最佳选择。我会改进答案以澄清struct 不是唯一可以使用的东西。
    • struct 是声明或定义类的关键字。 “结构”不是一个东西。
    【解决方案3】:

    我们几乎可以在不使用 lambda 的情况下完成所有事情。然而,引入 lambda 是为了支持函数式编程,并且在许多情况下都很有用。

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

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

    这里有两个明显的好处

    1. lambda 阻止创建全局或类静态函数
    2. 我不需要将参数传递给线程(这是一件很复杂的事情),因为 lambda 闭包可以解决这个问题。

    所以在少数情况下 lambda 可能是更好的选择,但这并不意味着我们不能对函数做同样的事情

    【讨论】:

      猜你喜欢
      • 2011-06-06
      • 2011-11-05
      • 2010-10-06
      • 2010-12-15
      • 2011-06-06
      • 1970-01-01
      • 2020-12-18
      • 1970-01-01
      相关资源
      最近更新 更多