c++ - Lambda 变量捕获

标签 c++ lambda c++11

我对 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/

相关文章:

c++ - 从字符串中读取可变数据

ruby - 在 Ruby 中引用另一个类的方法

c++ - 具有 lambda : how to compile? 的 max_element

c++ - 引用你不拥有的 "std::unique_ptr"(使用原始指针?)

c++ - 使用另一个类的 unique_ptr 设置回调函数

c++ - 凭据提供程序 'SetComboBoxSelectedValue' 未使用附加字段调用

entity-framework - Entity Framework Linq 将 lambda 表达式嵌入到可重用函数中

macos - µWebSockets 的 React Native OSX CRNA 编译未能通过 C++11 编译器

c++ - 如何为模板特化设置别名?

c++ - 使用 initializer_list 的模糊重载解析