我对 lambda 表达式的变量捕获部分的性质感到困惑。
void f1();
std::function<int()> f2;
int main() {
f1();
std::cout<<f2()<<endl;
}
void f1() {
int x;
f2 = [&]() {
return x;
};
}
在调用f2
之前,x
不是已经解构了吗?
最佳答案
是的。您已成功调用未定义的行为。一种可能的结果是您获得了 x 的值。另一个是计算机格式化您的硬盘驱动器、程序崩溃,或者计算机变成了一个机器人面包师,给您喂纸杯蛋糕,误以为您患有乳糜泻。
一个安全的变体可能是:
int main() {
f1(7);
std::cout<<f2()<<endl;
}
void f1(int x) {
std::shared_ptr<int> spX( new int(x) );
f2 = [=]() {
return *spX;
};
}
或
void f1(int x) {
f2 = [=]() {
return x;
};
}
(对于 int,没有理由不按值存储它:对于更复杂的类型,您可能希望避免不必要地复制它)。
请注意,上面的评论以一种更有趣的方式解释了这一点。
现在,一些编译器会在您递减堆栈时用特殊值标记堆栈以准确捕获这种未定义的行为(并且通过捕获,我的意思是使它对程序员更明显)。但在大多数情况下,调用 C++ 中的未定义行为是可能的。
关于c++ - Lambda 变量捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13093407/