Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is 'mutable' a lambda function attribute, instead of being a capture type?

Tags:

c++

c++11

Why does c++11 require us to write:

[a,b]() mutable { a=7; } // b is needlessly mutable, potential source of bugs 

Instead of:

[mutable a,b]() { a=7; } // no problems here 

Is this an oversight, considered not important enough, or is there a specific technical reason?

like image 790
mmocny Avatar asked Dec 27 '12 03:12

mmocny


People also ask

What is mutable in lambda?

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.

Does lambda capture reference by value?

Lambdas always capture objects, and they can do so by value or by reference.

What is auto lambda expression?

Immediately invoked lambda expression is a lambda expression which is immediately invoked as soon as it is defined. For example, #include<iostream> using namespace std; int main(){ int num1 = 1; int num2 = 2; // invoked as soon as it is defined auto sum = [] (int a, int b) { return a + b; } (num1, num2);


2 Answers

There is a mention about your suggestion in n2651:

The syntax for lambda expressions could be extended to allow declaring whether the closure members should be declared mutable or not.

This approach could be confusing to programmers, as the mutability is not a property of the closure object, but rather the variables stored in the closure.

I don't know if this is the only reason, but it does seem like it was considered. However, in Herb Sutter's proposal, he suggests getting rid of mutable and not making the capture copies implicitly const, so we might see changes again.

like image 147
Jesse Good Avatar answered Sep 23 '22 01:09

Jesse Good


Probably an oversight (in the same way as rvalue refs can't be used) of sorts and an artifact of the way lambdas are conceptually implemented.

int   a; int*  b; float c;  auto lambda1 = [&a, b, c](int d) mutable -> void {};  class lambda1 { public:     void operator()(int d) {} private:     int&  a_;     int*  b_;     float c_; };  auto lambda2 = [&a, b, c](int d) -> void {};  class lambda2 { public:     void operator()(int d) const {} private:     int&  a_;     int*  b_;     float c_; }; 
like image 40
Brandon Avatar answered Sep 21 '22 01:09

Brandon