AlgoMaster Logo

Lambda Expressions

Last Updated: January 3, 2026

7 min read

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.

What are Lambda Expressions?

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:

  • Capture: This part allows you to define what variables from the surrounding scope you want to use within your lambda.
  • Parameters: Just like in any function, these are the inputs your lambda can take.
  • Return type: This is optional; if omitted, the compiler tries to deduce the type.
  • Function body: This contains the code that will execute when the lambda is called.

Example of a Basic Lambda

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.

Capturing Variables

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.

Capture by Value

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.

Capture by Reference

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.

Using Lambdas with Standard Algorithms

Lambda expressions shine when used with standard algorithms from the C++ Standard Library. They allow for quick and easy inline function definitions.

Example with std::sort

Consider 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.

Example with std::for_each

You 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.

Edge Cases and Nuances

While lambda expressions are powerful, there are some subtle aspects that can trip you up. Let’s explore a few critical edge cases.

Capturing this Pointer

When 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.

Default Capture

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.

Real-World Applications

Lambda expressions can significantly improve the clarity and efficiency of your code. Here are a few common use cases:

Event Handling

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.

Multi-threading

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.