我对 lambda 表达式的变量捕获部分的性质感到困惑。
void f1();
std::function<int()> f2;
int main() {
f1();
std::cout<<f2()<<endl;
}
void f1() {
int x;
f2 = [&]() {
return x;
};
}
不是在调用x
之前解构吗?f2
Yes. You have successfully invoked undefined behavior. One possible outcome is that you get the value of x. Another is that the computer formats your hard drive, the program crashes, or the computer transforms into a robotic baker-assassin that feeds you cupcakes, mistakenly thinking you have celiac disease.
A safe variant of this might be:
int main() {
f1(7);
std::cout<<f2()<<endl;
}
void f1(int x) {
std::shared_ptr<int> spX( new int(x) );
f2 = [=]() {
return *spX;
};
}
or
void f1(int x) {
f2 = [=]() {
return x;
};
}
(for an int, there is little reason not to store it by value: for a more complex type, you might want to avoid copying it around needlessly).
Note that the comment above explains this in a funnier way.
Now, some compilers will mark the stack with special values when you decrement it to catch exactly this kind of undefined behavior (and by catch, I mean make it more obvious to the programmer). But for the most part, invoking undefined behavior in C++ is possible.
x 在调用 f2 之前不是解构了吗?
是的。这意味着return x
评估一个悬空引用,它调用未定义的行为。
在这种情况下,您可能更喜欢按值捕获。
f2 = [x]() { return x; }