7

假设我有以下内容。

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; };
    }
}

现在我有以下代码。

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

其中f#指的是任何一个f1, f2, f3, f4, f5

这些函数表现出以下两组之一的行为:

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

我知道这是因为有些人this在 的成员函数中A隐式或显式地捕获“”。

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

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

4

1 回答 1

8

没有确定这种行为的正式规则。因为这种行为是未定义的。

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

例外是f5,它应该返回一个一致的值,保证。它与原始对象完全断开。

于 2013-03-25T06:15:59.953 回答