我有一个非常简单的递归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
sum_v2
在创建lambda的同时,如何将参数first
视为2。我正在努力理解这一点。
能否请您给我一些提示以更好地理解这一点?我在rhel 7上使用带有-std = c ++ 17的gcc.9.2.0。
谢谢, 高拉夫
答案 0 :(得分:3)
此:
auto sum_v2 = [](auto first){
return [&first](auto second){
return first + second;
};
};
是未定义的行为,因为您要引用局部变量first
,该变量的生命周期在使用前就结束了。与所有UB一样,任何事情都可能发生。在您的计算机上,似乎first
最终引用了second
,但这并不能保证。该代码可能会在其他系统上崩溃,或产生预期的结果,但是您不能依靠它。
使用-Wall -Werror
甚至无法编译此错误代码。演示:https://godbolt.org/z/3gYx7q