Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are member variables captured by an "all automatic" capture, but not by explicit naming?

Tags:

c++

c++11

lambda

In C++11 (from cppreference.com):

[&] captures all automatic variables used in the body of the lambda by reference and current object by reference if exists

And...

[a,&b] where a is captured by copy and b is captured by reference

So my question is, if we have a class such as (VERSION A):

class Foo
{
    public:

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

    int x;    
};

In Line 6, we successfully capture the member variable x using the "all automatic variables by reference" capture specifier.

Or we can write (VERSION B):

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

But the following does not compile (VERSION C):

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

This is because x does not exist as a name in the enclosing scope.

This also does not compile (VERSION D):

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

This is because this cannot be captured by reference.

So, my question is, why does VERSION A work and not VERSION C or VERSION D? I understand why VERSION C and D do not work, but I don't understand why A works.

If we can't capture this by reference, and we cannot capture variables not in the parent scope, how is x being captured in VERSION A?

Intuitively, according to the capture rules VERSION B is the only version I'd expect to work.

like image 368
j b Avatar asked Jul 19 '18 08:07

j b


1 Answers

Version A works because *this is implicitly captured by reference.

The current object (*this) can be implicitly captured if either capture default is present.

When you specify capture default (the [&] in this case), *this is implicitly captured; which has the same effect as [this]. Note that what's captured by reference is *this, not this itself; this can't be captured explicitly by reference like [&this], so version D fails.

like image 98
songyuanyao Avatar answered Oct 21 '22 19:10

songyuanyao