为什么通过“全自动”捕获而不是通过显式命名捕获成员变量?

时间:2018-07-19 08:48:05

标签: c++ c++11 lambda

在C ++ 11中(来自cppreference.com):

  

[&]捕获lambda主体中使用的所有自动变量,方法是:   参考和当前对象(如果存在)

然后...

  

[a,&b]其中a被副本捕获,b被引用捕获

所以我的问题是,如果我们有(VERSION A)这样的类:

class Foo
{
    public:

    void test()
    {
        auto y = [&](){ return x; }();   // Line 6
    }

    int x;    
};

在第6行中,我们使用“所有自动引用变量”捕获说明符成功捕获了成员变量x

或者我们可以写(版本B):

{
    int& x = this->x;
    auto y = [&x](){ return x; }();
}

但是以下代码无法编译(版本C):

{
    auto y = [&x](){ return x; }();
}

这是因为x在封闭范围内不存在。

这也不会编译(版本D):

{
    auto y = [&this](){ return x; }();
}

这是因为无法通过引用捕获this

所以,我的问题是,为什么可以使用版本A,而不可以使用版本C或版本D?我理解为什么版本C和D不起作用,但是我不明白为什么A起作用。

如果我们无法通过引用捕获this,并且无法捕获不在父范围内的变量,那么x是如何在版本A中捕获的?

直觉上,根据捕获规则,VERSION B是我期望的唯一版本。

1 个答案:

答案 0 :(得分:13)

版本A之所以有效,是因为*this被引用隐式captured

  

如果存在任何捕获默认值,则可以隐式捕获当前对象(* this)。

指定捕获默认值(在这种情况下为[&])时,*this被隐式捕获;与[this]具有相同的作用。请注意,通过引用捕获的是*this,而不是this本身; this无法像[&this]那样被引用明确捕获,因此版本D失败。