我有一个关于调用lambda函数的问题,如SO文档中所述。
int multiplier = 5;
auto timesFive = [multiplier](int a) { return a * multiplier; };
std::cout << timesFive(2); // Prints 10
multiplier = 15;
std::cout << timesFive(2); // Still prints 2*5 == 10
为什么不打印2 * 15 = 30
?
显然,正在修改乘数的值,当调用timesFive
时,它应该选择multiplier
的更新值。
答案 0 :(得分:3)
您需要捕获而不是值,而是引用:
只需使用&multiplier
代替multiplier
。
您链接到的Lambda函数的SO文档说:
[]
是捕获列表。默认情况下,lambda无法访问封闭范围的变量。 捕获变量使其可以在lambda中访问,可以是副本,也可以是引用。 捕获的变量成为lambda的一部分; 与函数参数相反,它们不必在调用lambda时传递。
int a = 0; // Define an integer variable
auto f = [a]() { return a*9; }; // OK, 'a' is "captured" by value
auto f = [&a]() { return a++; }; // OK, 'a' is "captured" by reference
答案 1 :(得分:2)
multiplier
由值捕获,因此在创建lambda函数时,它会在闭包对象中复制。
您可以根据需要将multiplier
local更改为外部函数,闭包内的副本将保持创建时的任何值。
您期望的结果是您通过引用捕获multiplier
时获得的结果,即在捕获列表中指定&multiplier
。请注意,在最后一种情况下,确保lambda不会超过引用捕获的变量的责任仅限于你的;只要你的lambda只是其包含函数的本地,它就可以了,但是如果你将它返回或存储在其他地方(例如在std::function
变量中)并且在父函数返回后调用它你会得到未定义的行为。
答案 2 :(得分:1)
通过引用捕获乘数:
auto timesFive = [&multiplier](int a) { return a * multiplier; };
答案 3 :(得分:0)
int multiplier = 5;
auto timesFive = [&multiplier](int a)->int{
return a*multiplier;
};
cout << timesFive(1) << "\n";
multiplier = 6;
cout << timesFive(2);
乘数需要通过引用捕获。如果要捕获所有可以写的变量
auto timesFive = [&](int a){return a * multiplier};