I've encountered a notation like:
int x = 4;
auto y = [&r = x, x = x+1]()->int {
r += 2;
return x+2;
}();
Can you explain this statement? I was a user of C++03 and recently upgraded to C++11. From today I starts C++14 and encountered this snippet.
Thanks!
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.
Much like functions can change the value of arguments passed by reference, we can also capture variables by reference to allow our lambda to affect the value of the argument. To capture a variable by reference, we prepend an ampersand ( & ) to the variable name in the capture.
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.
A lambda is an object (hence why we're referring to it as a functor, rather than a function) so has a type and can be stored. However, the type of the lambda is only known by the compiler (since it is compiler-generated), so you must use auto for declaration instances of the lambda.
Thanks @chris for the wikipedia reference. What I found is -
Here is nice explanation who don't know about the old lambda Captures of C++11
In C++14:
C++11 lambda functions capture variables declared in their outer scope by value-copy or by reference. This means that value members of a lambda cannot be move-only types. C++14 allows captured members to be initialized with arbitrary expressions. This allows both capture by value-move and declaring arbitrary members of the lambda, without having a correspondingly named variable in an outer scope.
This is done via the use of an initializer expression:
auto lambda = [value = 1] {return value;};
The lambda function
lambda
will return 1, which is whatvalue
was initialized with. The declared capture deduces the type from the initializer expression as if byauto
.This can be used to capture by move, via the use of the standard
std::move
function:std::unique_ptr<int> ptr(new int(10)); auto lambda = [value = std::move(ptr)] {return *value;};
So the above expression updates x to 6, and initializes y to 7.
This example is part of C++14 feature "Lambda capture Initializers", This allows creating lambda captures initialized with arbitrary expressions. Using this reference-captures can have different names than the referenced variable.
If you run your code :
int x = 4;
auto y = [&r = x, x = x+1]()->int {
r += 2; //r=6
return x+2;//5+2
};
cout<<y()<<endl; // this will print 7
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With