Search code examples
c++lambdainitializationc++14

Accessing lambda capture initialized variable outside the lambda in C++


In C++14/17, how do you access a lambda capture initialized variable outside the scope of the lambda?

Source:

#include <iostream>

using namespace std;

int main(){
    auto test = [value1 =0]() mutable {value1+=1; return value1;};
    cout << test() << endl;
    cout << test() << endl;
    //cout << value1 << endl;//error: ‘value1’ was not declared in this scope
}

Output:

1

2

Is the value1 variable accessible outside the scope of the test() lambda? What is the lifetime of a lambda capture initialized variable?

Attempting to access value1 outside the lambda gives the following error: ‘value1’ was not declared in this scope.

Compiled with gcc version 7.3.0 (Ubuntu 7.3.0-21ubuntu1~14.04).


Solution

  • A lambda is just a compact definition for an inline-defined struct and an operator() overload on that struct (and for creating an object of that struct's type). Lambda "captures" are just member variables of this struct, initialized by the type's constructor. This is one reason why C++ lambdas have to have syntax for capturing by value vs. by reference.

    But the members variables of the struct are private. And since the compiler-generated struct is largely implementation-defined, it isn't required by the standard to expose those members with those names. The compiler-generated struct could use some other name if it wanted; the compiler would just have to remap the in-lambda usage of those names to reference the members' names.

    So no, lambda captures of any kind cannot be accessed by the world outside of that lambda. If you capture a reference to an object, then its possible for the outside world to access the same object. But you would not be accessing the same reference to that object.