Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ lambda copy value in capture-list

Tags:

c++

c++11

lambda

I have a program as below:

int main()
{
    int val = 4;
    auto add = [val](int a)->int{
        val += 2;
        return a+val;
    };
    cout << add(3) << endl;
    cout << val << endl;
    return 0;
}

There's a compiling error in Xcode: Cannot assign to a variable captured by copy in a non-mutable lambda.

My question is: if we choose to use the copy (using "=" or value name), can't this value be assigned a new value or changed?

like image 753
injoy Avatar asked Sep 13 '14 21:09

injoy


People also ask

How do you capture variables in lambda?

Capture clause A lambda can introduce new variables in its body (in C++14), and it can also access, or capture, variables from the surrounding scope. A lambda begins with the capture clause. It specifies which variables are captured, and whether the capture is by value or by reference.

What is lambda capture clause?

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.

Where are lambda captures stored?

Lambda expressions can capture of outer scope variables into a lambda function. The captured variables are stored in the closure object created for the lambda function.

What is capture list in lambda C++?

The capture list defines the outside variables that are accessible from within the lambda function body. The only capture defaults are. & (implicitly capture the used automatic variables by reference) and. = (implicitly capture the used automatic variables by copy).


1 Answers

Inside a lambda, captured variables are immutable by default. That doesn't depend on the captured variables or the way they were captured in any way. Rather, the function call operator of the closure type is declared const:

This function call operator or operator template is declared const (9.3.1) if and only if the lambda-expression’s parameter-declaration-clause is not followed by mutable.

Therefore, if you want to make the captured variables modifiable inside the body, just change the lambda to

auto add = [val] (int a) mutable -> int {
    val += 2;
    return a+val;
};

so the const-specifier is removed.

like image 100
Columbo Avatar answered Oct 11 '22 18:10

Columbo