Yes, it's possible to create a lambda that maintains state across multiple invocations. This is achieved by capturing variables by reference.
Here's an example:
#include <iostream>
int main() {
int counter{0};
auto IncrementCounter{[&counter]() {
++counter;
std::cout << "Counter: " << counter << '\n';
}};
IncrementCounter();
IncrementCounter();
IncrementCounter();
}
Counter: 1
Counter: 2
Counter: 3
In this code, counter
is a local variable in main
. We create a lambda IncrementCounter
that captures counter
by reference.
Inside the lambda, we increment counter
and print its value. Because counter
is captured by reference, any changes made to it inside the lambda are reflected outside the lambda.
Each time IncrementCounter
is called, it increments and prints the same counter
variable. Thus, the output shows the counter increasing with each invocation.
This technique can be used to create lambdas that maintain internal state, similar to a small function object.
However, it's important to be careful with this technique. If the captured reference outlives the original variable, you'll have a dangling reference and undefined behavior. For example:
auto MakeLambda() {
int counter{0};
return [&counter]() {
++counter;
};
}
int main() {
auto Lambda{MakeLambda()};
Lambda(); // Undefined behavior
}
Here, counter
is a local variable in MakeLambda
. The lambda captures it by reference and is then returned from the function. However, when MakeLambda
ends, counter
is destroyed. Thus, when we later call Lambda
, it's referencing a variable that no longer exists.
To avoid this, you can capture by value instead of by reference. This creates a copy of the variable that the lambda owns, avoiding dangling references:
auto MakeLambda() {
int counter{0};
return [counter]() mutable {
++counter;
};
}
Note that we need to mark the lambda as mutable
in this case, as we're modifying a captured value.
Answers to questions are automatically generated and may not have been reviewed.
An introduction to lambda expressions - a concise way of defining simple, ad-hoc functions