【发布时间】:2017-05-17 01:52:21
【问题描述】:
今天我在 C++11 lambdas 中遇到了一个非常不直观的行为(至少对我而言)。有问题的代码如下:
#include <stdio.h>
auto sum(int x) {
return [&x](int y) {
return x + y;
};
}
int main() {
int a = sum(2)(3);
printf("%d\n",a);
}
这不是打印 5,而是打印乱码。实际上,至少在我的 GCC 版本中,如果我打开 -O2 优化标志,它实际上会打印 5。由于输出取决于编译器的优化级别,因此它是未定义的行为。过了一会儿,我想我明白发生了什么。
当函数 sum 被调用时,对应于参数 x 的堆栈变量被设置为 2,然后函数 sum 返回,并且这个堆栈变量可能被编译器需要放在那里的任何东西覆盖以执行以下代码,当 lambda 最终被执行时,x 所在的位置不再是 2,程序将 3 添加到任意整数。
有没有什么优雅的方式在 C++ 中进行柯里化以保证变量被正确捕获?
【问题讨论】:
-
按值捕获
[=]。 -
谢谢!这比我预期的要简单得多。
-
仅供读者参考,这是 C++14,而不是 C++11。 C++14增加了函数返回值的类型推导。
-
我用 g++ -std=c++11 编译,从 --version 的输出来看似乎是 2013 年的。也许这是 GCC 对 C++11 的非标准扩展?
-
我认为这是对 GCC 的扩展,不应使用严格的编译器标志来允许