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ます。

これらの関数は、次の2つのセットのいずれかで動作を示しています。

  1. 呼び出されたときに5を返す(f5)、または
  2. 逆参照しようとしてクラッシュしましたnullptrf1, f2, f3, f4)。

これは、暗黙的または明示的に、thisのメンバー関数で""をキャプチャしているためであると理解しています。A

行動1または2を決定する正式なルールは何ですか?

に似たものによって引き起こされたバグに対処するためにしばらく時間を費やし、f1それがキャプチャされるとは考えていましたが、キャプチャxされるとは考えていなかったthisので、これを文書化すると便利だと思いました。

4

1 に答える 1

8

この動作を決定する正式なルールはありません。この動作は未定義であるためです。

ラムダが存在しないオブジェクトにアクセスしています。メンバー変数を値で直接キャプチャすることはできません。常にそれらをキャプチャしますthis。つまり、参照によってそれらをキャプチャしているということです。オブジェクトが削除されると、その削除されたオブジェクトにアクセスしようとすると、未定義の動作が発生します。

これの例外はf5、保証された一貫した値を返す必要があるです。元のオブジェクトから完全に切断されています。

于 2013-03-25T06:15:59.953 に答える