Lambda Functions

reading

A nice lambda cheatsheet is available from hackingcpp.com.

C++ has another type of function called a lambda function. You can think of a lambda as an anonymous function that can capture data directly from its environment and work on it. Lambda functions are typically used when you only need to use a function in a single place.

The general form of a lambda is:

[ capture clause ] ( arguments ) { statements };

with optionally some specifiers between the arguments and statements.

The capture clause tells the compiler how it can access data from the surrounding scope:

  • [=] means it captures objects by value

  • [&] means it captures objects by reference

mixed types of capture are also possible, where you can capture some data by value and others by reference

Here’s a simple example:

Listing 28 lambda_examples.cpp
#include <iostream>

int main() {

    double x{10.0};

    auto f = [=] (double y) {return x + y;};

    std::cout << f(1) << " " << f(2) << " " << f(3) << std::endl;

    auto g = [&] () {x *= 2; return x;};

    std::cout << g() << " " << g() << " " << g() << std::endl;

    std::cout << "x = " << x << std::endl;
    
}

Sort Example

Lambdas make it easy to provide simply functions as arguments to other functions (like we did with std::sort() previously). Here’s an implementation of that using a lambda function:

Listing 29 algorithms_functions_lambda.cpp
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

int main() {

    std::vector<std::string> titles{"a new hope",
                                    "the empire strikes back",
                                    "return of the jedi",
                                    "the phantom menace",
                                    "attack of the clones",
                                    "revenge of the sith",
                                    "the force awakens",
                                    "the last jedi",
                                    "the rise of skywalker"};

    std::sort(titles.begin(), titles.end());

    for (auto e : titles) {
        std::cout << e << std::endl;
    }
    std::cout << std::endl;

    // now sort by string length

    std::sort(titles.begin(), titles.end(),
              [] (const std::string& a, const std::string& b) {return a.size() < b.size();});

    for (auto e : titles) {
        std::cout << e << std::endl;
    }
    std::cout << std::endl;

}