Lambdas

Creating Stateful Lambdas

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

Abstract art representing computer programming

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.

A computer programmer
Part of the course:

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

This course includes:

  • 125 Lessons
  • 550+ Code Samples
  • 96% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved