C ++ Lambdas:捕获列表与参数列表

时间:2015-02-23 08:56:11

标签: c++ c++11 lambda

根据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 ++函数一样),为什么我们需要捕获列表呢?

有人可以向我展示参数列表不起作用且仅捕获列表的情况吗?

3 个答案:

答案 0 :(得分:20)

例如使用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,则返回。 代码没有多大意义,它只是向您展示捕获和参数列表很重要的示例。

答案 1 :(得分:7)

关键在于,通过捕获,您可以在类似函数的对象中保持一个状态(就像一个带有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;
}

答案 2 :(得分:-2)

我是第一次使用Capture List功能。它看起来像一个很棒的功能,用户可以借此机会从函数的外部范围定义要捕获的数据。

阅读JS中的闭包将提供有关此功能的更多上下文。在JS中,函数会捕获其外部作用域中存在的每个变量,这些变量可能是浪费的甚至是不安全的。