简体   繁体   English

Lambda变量捕获

[英]Lambda variable capture

I'm confused about the nature of the variable capture part of a lambda expression. 我对lambda表达式的变量捕获部分的性质感到困惑。

void f1();
std::function<int()> f2;

int main() {
    f1();
    std::cout<<f2()<<endl;
}

void f1() {
    int x;
    f2 = [&]() {
        return x;
    };
}

Isn't x deconstructed before f2 is called? 在调用f2之前x不会被解构吗?

Yes. 是。 You have successfully invoked undefined behavior. 您已成功调用未定义的行为。 One possible outcome is that you get the value of x. 一种可能的结果是您得到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). (对于int,没有理由不按值存储它:对于更复杂的类型,您可能要避免不必要地对其进行复制)。

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). 现在,当您递减堆栈以恰好捕获这种未定义的行为时,某些编译器将使用特殊值标记堆栈(通过catch,我的意思是使堆栈对程序员更明显)。 But for the most part, invoking undefined behavior in C++ is possible. 但是在大多数情况下,可以在C ++中调用未定义的行为。

Isn't x deconstructed before f2 is called? 在调用f2之前x不会被解构吗?

Yes, it is. 是的。 Which means that the return x evaluates a dangling reference, which invokes undefined behavior. 这意味着return x评估一个悬空引用,该引用引用了未定义的行为。

In this instance, you might prefer to capture by value. 在这种情况下,您可能更喜欢按值捕获。

f2 = [x]() { return x; }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM