Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why lambda captures only automatic storage variables?

Tags:

I just started learning lambda functions in C++ and i don't understand why lambda's allow capturing only automatic storage variables? For example:

int x;
int main() {
    [&x](int n){x = n;}; // 'x' cannot be captured...
    return 0;
}

On the other hand static variables don't need capturing at all

static int s = 0;
[](int n){s = n;};

So, why the first example is not allowed and the second works?

like image 351
Tracer Avatar asked Jun 29 '14 09:06

Tracer


People also ask

Are lambda captures Const?

By default, variables are captured by const value . This means when the lambda is created, the lambda captures a constant copy of the outer scope variable, which means that the lambda is not allowed to modify them.

Does lambda capture reference by value?

The mutable keyword is used so that the body of the lambda expression can modify its copies of the external variables x and y , which the lambda expression captures by value. Because the lambda expression captures the original variables x and y by value, their values remain 1 after the lambda executes.

What does it mean to lambda capture this?

The lambda is capturing an outside variable. A lambda is a syntax for creating a class. Capturing a variable means that variable is passed to the constructor for that class. A lambda can specify whether it's passed by reference or by value.

What are captures in C++ lambda?

A capture clause of lambda definition is used to specify which variables are captured and whether they are captured by reference or by value. An empty capture closure [ ], indicates that no variables are used by lambda which means it can only access variables that are local to it.


2 Answers

You need to go back and ask yourself: Why do lambdas capture variables at all?

Lambdas can use variables from an outer scope. However, if those are local variables, they go out of scope and cannot be used after the function returns. But a lambda could potentially be called after the function returns (the lambda could be returned from the function, or stored in some global or instance variable, etc.), and after the function returns, it cannot just refer to the local variables directly, because they no longer exist.

That's why lambdas can capture local variables by copy (copy their value at the time the lambda is created). (They can also capture by reference, as an alternative to by copy.)

The above issue only exists for variables of automatic storage duration. For variables of static storage duration (e.g. global variables, static local variables), they live for the lifetime of the program, and there is no problem with accessing them at any time.

like image 148
newacct Avatar answered Dec 28 '22 14:12

newacct


You need to change scope. Look at this:

int x = 4;

int main()
{
    cout << "::x = " << ::x << endl;

    [&](int a){ ::x = a; }(2);

    cout << "::x = " << ::x << endl;

    return 0;
}

Output:

::x = 4
::x = 2
like image 29
Dakorn Avatar answered Dec 28 '22 14:12

Dakorn