Creating Stateful Lambdas

Is it possible to create a lambda that maintains state across multiple invocations?

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.

Lambdas

An introduction to lambda expressions - a concise way of defining simple, ad-hoc functions

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Capturing Class Members in Lambdas
How can I capture member variables of a class when defining a lambda inside a member function?
Returning Lambdas from Functions
Can I return a lambda from a function? If so, how do I specify the return type?
Using Lambdas in Template Functions
How can I pass a lambda as an argument to a function template?
Using Lambdas as Comparators
Can I use a lambda as a comparator for STL containers and algorithms?
Creating Recursive Lambdas
Can a lambda call itself recursively?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant