What are the pitfalls of using lambda default capture by value ([=]
) or by reference ([&]
) in C++11?
I know some pitfalls like:
Does default capturing by value have any disadvantages?
One of the new features introduced in Modern C++ starting from C++11 is Lambda Expression. It is a convenient way to define an anonymous function object or functor. It is convenient because we can define it locally where we want to call it or pass it to a function as an argument.
Lambdas can both capture variables and accept input parameters. A parameter list (lambda declarator in the Standard syntax) is optional and in most aspects resembles the parameter list for a function. auto y = [] (int first, int second) { return first + second; };
A lambda expression can refer to identifiers declared outside the lambda expression. If the identifier is a local variable or a reference with automatic storage duration, it is an up-level reference and must be "captured" by the lambda expression.
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.
Capturing by value using [=]
or [<identifier>]
has the effect of creating a lambda member of the exact same type as the captured entity, including constness, e.g., when capturing a const int
by value, the resulting member can not be mutated even when the lambda call operator is mutable.
const int i = 1;
[=] () mutable { ++i; }(); // Error: increment of read-only variable.
This can be worked around using C++14's initializing capture expressions:
[i = i] () mutable { ++i; }(); // Ok
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