LibraryLambda Expressions

Lambda Expressions

Learn about Lambda Expressions as part of C++ Modern Systems Programming and Performance

C++ Lambda Expressions: Concise, Inline Functions

Lambda expressions, introduced in C++11, provide a powerful and convenient way to define anonymous functions inline. They are particularly useful for passing small pieces of functionality to algorithms or for creating local helper functions without the need for a separate named function definition. This makes your code more readable and expressive, especially when dealing with the Standard Template Library (STL).

The Anatomy of a Lambda Expression

Lambdas are like mini-functions you can write right where you need them.

A lambda expression consists of a capture clause, parameter list, return type (optional), and a body. It's a compact way to define a function object.

The general syntax of a C++ lambda expression is:

[capture_clause](parameter_list) mutable exception_specification -> return_type { function_body }

  • Capture Clause ([...]): Specifies how variables from the surrounding scope are accessed within the lambda. Common captures include [] (no capture), [=] (capture by value), [&] (capture by reference), and [var1, &var2] (capture specific variables).
  • Parameter List ((...)): Similar to function parameters. If omitted, it implies no parameters.
  • Mutable (mutable): Allows modification of captured-by-value variables within the lambda's body.
  • Exception Specification (noexcept, etc.): Declares whether the lambda can throw exceptions.
  • Return Type (-> return_type): Explicitly specifies the return type. Often, the compiler can deduce this, making it optional.
  • Function Body ({...}): The code that the lambda executes.

Capturing Variables: Accessing the Outside World

The capture clause is crucial for making lambdas useful. It determines how the lambda can interact with variables defined outside its own scope. Understanding capture modes is key to avoiding unintended side effects and ensuring correct behavior.

Capture ModeDescriptionUse Case Example
[] (Empty)No variables from the surrounding scope are captured.Lambdas that operate solely on their parameters.
[=] (Capture by Value)All variables used in the lambda are captured by value (a copy is made).When you need to use a variable's value at the time the lambda is defined, and you don't want it to change if the original variable is modified later.
[&] (Capture by Reference)All variables used in the lambda are captured by reference (a reference to the original variable is used).When you need to modify the original variable or when copying is expensive and you are sure the original variable will remain in scope.
[var]Captures a specific variable var by value.Explicitly capturing only necessary variables by value.
[&var]Captures a specific variable var by reference.Explicitly capturing only necessary variables by reference.
[=, &var]Captures all used variables by value, except var, which is captured by reference.A mix of capture modes for fine-grained control.

Lambdas with STL Algorithms

Lambdas are most commonly used with STL algorithms like

code
std::sort
,
code
std::for_each
,
code
std::transform
,
code
std::find_if
, and
code
std::count_if
. They allow you to customize the behavior of these algorithms directly where they are called.

Consider sorting a vector of integers in descending order. Traditionally, you'd define a separate comparison function. With a lambda, you can do this inline:

std::vector<int> numbers = {5, 2, 8, 1, 9}; std::sort(numbers.begin(), numbers.end(), [](int a, int b) { return a > b; });

Here, [](int a, int b) { return a > b; } is the lambda. It takes two integers (a and b) and returns true if a should come before b in the sorted sequence (i.e., a is greater than b for descending order). This lambda is passed as the third argument to std::sort, acting as a custom comparator.

📚

Text-based content

Library pages focus on text content

Return Type Deduction and Explicit Return Types

For simple lambdas where the body consists of a single

code
return
statement, the compiler can usually deduce the return type. However, for more complex bodies or when you need explicit control, you can specify the return type using the
code
-> return_type
syntax.

What is the primary advantage of using lambda expressions with STL algorithms?

They allow for inline, custom behavior definition, making code more concise and readable without needing separate named functions.

Common Pitfalls and Best Practices

Be mindful of capture-by-reference ([&]) when the lambda might outlive the scope of the captured variables. This can lead to dangling references and undefined behavior.

When capturing by value (

code
[=]
), remember that the lambda operates on a copy. If you need to modify the captured variable within the lambda, you must also use the
code
mutable
keyword. For complex operations or when the lambda needs to be reused, consider defining a named function or a functor for better maintainability.

Learning Resources

C++ Lambda Expressions - cppreference.com(documentation)

The definitive reference for C++ lambda expressions, covering syntax, capture clauses, and advanced features.

C++ Lambda Expressions Tutorial - LearnCpp.com(tutorial)

A comprehensive tutorial explaining lambda expressions with clear examples and explanations of capture clauses and usage.

Modern C++: Lambda Expressions - Scott Meyers(video)

A video by Scott Meyers, a renowned C++ expert, discussing the power and nuances of lambda expressions.

Using Lambdas with STL Algorithms - GeeksforGeeks(blog)

Demonstrates practical applications of lambda expressions with various C++ Standard Template Library algorithms.

C++11 Lambda Expressions Explained - CodeProject(blog)

An in-depth article breaking down the syntax, features, and benefits of C++11 lambda expressions.

Effective Modern C++: Item 34: Prefer lambdas to anonymous functions(paper)

An excerpt from Scott Meyers' influential book, advocating for the use of lambdas over older methods for inline functions.

C++ Lambda Expressions - Tutorialspoint(tutorial)

A straightforward guide to understanding the syntax and basic usage of C++ lambda expressions.

Understanding C++ Lambda Capture Clauses - Fluent C++(blog)

A detailed exploration of different capture modes in C++ lambdas and their implications.

C++ Lambda Expressions - Microsoft Docs(documentation)

Official documentation from Microsoft on C++ lambda expressions, including syntax and examples.

C++ Lambda Expressions - Wikipedia(wikipedia)

An overview of lambda expressions in programming, with a specific section detailing their implementation and use in C++.