Flo Flo - 2 months ago 13
C++ Question

Access two-step-declared member in lambda setup

Don't know how to describe it better. Here's the code. This fails to compiler on gcc 4.9.2 (Debian 8.5), tough I think it compiled in a previous version. The problem seems to occur only if I access the later-declared structure's member as a default argument in the lambda setup. The other shown cases work.

// Test program
class C1
{
private:
// Forward-declared
struct S_Private;
S_Private* d_;

public:
void func();
};

struct C1::S_Private
{
int a;
};

void C1::func()
{
// This will work
int test = d_->a;

// Accessing the d_->a as a default argument in lambda setup
// will NOT work:
// error: invalid use of non-static data member ‘C1::d_’
auto some_lambda = [&](int arg = d_->a)
{
// This will also work
int test2 = d_->a;
};
}

int main(void)
{
}

Answer

Unfortunately in auto some_lambda = [&](int arg = d_->a), d_->a is not the d_->a you used earlier in the function but instead d_->a is being called on the this that you captured using [&]. Because it is a member variable you cannot use it as a default argument in a function.

Essentially

auto some_lambda = [&](int arg = d_->a)
{
    // This will also work
    int test2 = d_->a;
};

Is

struct some_unique_name
{
    some_unique_name(C1*& var) : this_(var) {}
    auto operator()(int arg = this_->d_->a)
    {
        // This will also work
        int test2 = d_->a;
    }
    C1*& this_;
};

auto some_lambda = some_unique_name{this};

As you can see from the translation it uses the class member, not the object in the class itself.

Comments