Last Updated: January 3, 2026
Lambda expressions in C++ are a powerful feature that allows you to define anonymous functions directly in the context where they are needed. They can make your code more concise and expressive, especially when dealing with algorithms and callbacks.
Let's dive into the world of lambda expressions and see how they can enhance your coding experience.
At its core, a lambda expression is a way to create a function object (or functor) without formally defining a function. This can be handy for short snippets of code that are used only once or twice.
The syntax of a lambda expression looks like this:
Let’s break this down:
Here’s a simple example that demonstrates the basic structure of a lambda:
In this example, we define a lambda that takes a std::string and prints a greeting. We then call the lambda with two different names. This is a classic case where using a lambda makes your code cleaner and more direct.
One of the most powerful features of lambda expressions is the ability to capture variables from the surrounding scope. You can capture variables either by value or by reference.
When you capture a variable by value, you get a copy of the variable as it was at the time the lambda was defined. Changes made to the variable after the lambda is defined do not affect the captured value.
Here’s an example:
Notice the mutable keyword in the lambda. It allows us to modify the captured variable within the lambda, but only the copy, not the original.
If you want to capture the original variable so that changes made inside the lambda affect it, you can capture by reference:
Here, the lambda captures number by reference, allowing us to increment the original variable directly.
Use capture by reference if you need to modify the original variable. Use capture by value if you want to ensure the original variable remains unchanged.
Lambda expressions shine when used with standard algorithms from the C++ Standard Library. They allow for quick and easy inline function definitions.
std::sortConsider a scenario where you need to sort a list of numbers in descending order. With a lambda, you can define the comparison on the fly:
In this example, the lambda expression defines the sorting criteria directly in the std::sort call. This keeps the code clean and avoids the need for a separate function definition.
std::for_eachYou can also use lambdas with std::for_each to apply an operation to each element in a collection:
This lambda takes each name and prints it, showcasing how you can encapsulate behavior in a concise way.
While lambda expressions are powerful, there are some subtle aspects that can trip you up. Let’s explore a few critical edge cases.
this PointerWhen working within a class, you may want to capture the this pointer to access member variables or methods:
Here, the lambda captures this so it can access the private member count.
Be careful when capturing this in lambdas that are stored beyond the scope of the class instance. This can lead to dangling pointers if the object is destroyed.
Starting from C++14, you can simplify your capture list using default capture:
In this case, all variables are captured by value except for x, which is captured by reference.
Lambda expressions can significantly improve the clarity and efficiency of your code. Here are a few common use cases:
When dealing with GUI programming or event-driven architectures, lambdas simplify callback management:
This approach allows you to define what should happen in response to an event without cluttering your code with function definitions.
In C++, lambdas are often used to encapsulate tasks for threading:
Here, a lambda is passed to a new thread, allowing us to define the work to be done inline.