【问题标题】:C++ Lambdas: capture list vs. parameter listC++ Lambdas:捕获列表与参数列表
【发布时间】:2015-02-23 08:56:11
【问题描述】:

根据 C++11 标准,lambda 表达式可以使用封闭范围内的变量,通过捕获列表、参数列表或两者兼而有之。

那么,让我们看看相同代码的两个版本。

1) 带捕获

int x = 4;

cout << "With capture  : Factorial of " << x << " = " << [x]() // <= Capture
{
    int r = 1;
    for (int i = x; i > 1; i--) r = r * i;
    return r;
}() << endl;

2) 带参数

int x = 4;

cout << "With parameter: Factorial of " << x << " = " << [](int x) // <= Parameter
{
    int r = 1;
    for (int i = x; i > 1; i--) r = r * i;
    return r;
}(x) << endl;

输出是:

With capture  : Factorial of 4 = 24
With parameter: Factorial of 4 = 24

既然我们可以在参数列表中向 lambdas 传递参数(就像使用任何 C++ 函数一样),为什么我们需要捕获列表?

谁能告诉我参数列表不起作用而只有捕获列表起作用的情况?

【问题讨论】:

    标签: c++ c++11 lambda


    【解决方案1】:

    例如使用stl算法:

    std::vector<int> items;
    int factor;
    auto foundItem = std::find_if(items.begin(), items.end(), 
    [&factor](int const& a) 
    { 
       return a * factor == 100; 
    });
    

    在这种情况下,您在 lambda 中为容器中的每个项目调用,如果乘以捕获因子的值是 100,则返回。 代码没有多大意义,它只是向您展示一个捕获和参数列表很重要的示例。

    【讨论】:

    • 我们不能在参数列表中同时传递整数 'a' 和 'factor' 并让捕获为空吗?
    • @Xicod'Abrolha 怎么样?你没有调用 lambda,std::find_if 正在这样做。你会如何让它以不同的方式调用函数?
    • 不,Xico,你不能!在 find_if 代码的某处,您有一些像这样调用您的 lambda(或函数)的东西: handler(value);对于范围开始/结束中的每个值。
    • 谢谢 dau_sama 和 Angew。最后我明白了捕获列表的需要。你的帮助比我读过的一堆书和我做的谷歌搜索更有价值。所以需要 15 次代表才能将答案标记为有帮助。我只有 11 个代表。不过,谢谢。
    • @Xicod'Abrolha:你不需要 15 个代表来接受一个答案,这就是你接受它时 dau_sama 会得到多少。接受答案没有最低代表(您将获得 2 个代表)。
    【解决方案2】:

    关键在于,通过捕获,您可以在类似函数的对象中保持状态(就像使用 operator() 的手写类一样)。 @dau_sama 给出了一个很好的答案。这是另一个例子:

    #include <iostream>
    using namespace std;
    
    int main() {
    
      const auto addSome = [](double some){
        return [some](double val){ return some+val; } ;
      };
    
      const auto addFive = addSome(5);
    
      std::cout << addFive(2) << std::endl;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-21
      • 2013-01-23
      • 2012-11-20
      • 1970-01-01
      相关资源
      最近更新 更多