我有一个非常简单的递归lambda,它计算给定2个数字的和:
auto sum_v1 = [](auto first){
return [first](auto second){
return first + second;
};
};
sum_v1 (1)(2); // returns 3, OK
现在具有相同的功能,首先使用引用捕获arg。
auto sum_v2 = [](auto first){
return [&first](auto second){
return first + second;
};
};
sum_v2 (1)(2); // returns 4, NOT OK
[sum_v2
获得参数first
作为2
,而arg second
也是2
。
我知道如何获得正确的结果。我可以使用sum_v1或sum_v3(如下所示)。
// accept arg first using r-value reference
auto sum_v3 = [](auto&& first){
return [first](auto second){
return first + second;
};
};
sum_v3 (1)(2); // returns 3, OK
[创建Lambda时sum_v2
的工作方式如何,将arg first
视为2。我正在努力理解这一点。
[能否请您给我一些提示以更好地理解这一点?我在rhel 7上使用带有-std = c ++ 17的gcc.9.2.0。
谢谢,高拉夫
此:
auto sum_v2 = [](auto first){
return [&first](auto second){
return first + second;
};
};
是未定义的行为,因为您正在引用一个局部变量first
,该变量的生命周期在使用前就结束了。与所有UB一样,任何事情都可能发生。在您的计算机上,似乎first
最终引用了second
,但这并不能保证。该代码可能会在其他系统上崩溃,或产生预期的结果,但您不能依靠它。
使用-Wall -Werror
,您甚至无法编译此错误代码。演示:https://godbolt.org/z/3gYx7q