根据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 ++函数一样),为什么我们需要捕获列表呢?
有人可以向我展示参数列表不起作用且仅捕获列表的情况吗?
答案 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中,函数会捕获其外部作用域中存在的每个变量,这些变量可能是浪费的甚至是不安全的。