Lambda表达偷偷地抓住了"这个"

Tim*_*lds 7 c++ lambda c++11

假设我有以下内容.

struct A
{
    int x;
    std::function<int()> f1() { return [=](){ return x; }; }
    std::function<int()> f2() { return [=](){ return this->x; }; }
    std::function<int()> f3() { return [this](){ return x; }; }
    std::function<int()> f4() { return [this](){ return this->x; }; }
    std::function<int()> f5()
    {
        int temp = x;
        return [=](){ return temp; };
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我有以下代码.

auto a = std::make_shared<A>();
a->x = 5;
std::function<int()> f = a.f#();
a.reset();
int x = f();
Run Code Online (Sandbox Code Playgroud)

在哪里f#指的是任何一个f1, f2, f3, f4, f5.

这些函数在两组中的一组中表现出行为:

  1. 在调用(f5)时返回5 ,或
  2. 试图取消引用崩溃nullptr(f1, f2, f3, f4).

我理解这是因为有些人thisA隐式或显式的成员函数中捕获" " .

确定行为1或2的正式规则是什么?

我花了一段时间来处理由类似的东西引起的错误f1,认为它会捕获x并且从不考虑它会捕获this,所以我认为记录它会很有用.

Nic*_*las 8

没有正式规则可以确定此行为.因为此行为未定义.

你的lambda正在访问一个不存在的对象.您无法直接按值捕获成员变量; 你总是抓住它们this.这意味着您通过引用捕获它们.删除对象后,任何访问该已删除对象的尝试都会导致未定义的行为.

例外情况是f5,应保证返回一致的值.它与原始对象完全断开连接.