C++ 11 – lambda expression

When you feel the needed functions are very small, concise, can be inline, and used only at that location, use lambda expression instead of a function. These are the conditions where we do not need to name a function as we do not need to call it elsewhere.

The lambda expression is more concise and readable. It also allows a C++ compiler to optimize well and generate better-performing code than a named function in many cases.

The lambda expression is as simple as below.

[](int x, int y) { return x + y; }
  • [ ] is where you can provide variable names that you require from the surrounding context.
  •  ( ) is where you can specify arguments for the lambda expression. In the above case, there are two int arguments, x, and y.
  •  { } consists of the body of the lambda expression. In the above case, it is just one line of code “return x + y;”.

Let us use a C++ example program to see how we use lambda expressions in different scenarios. The program is available for download at https://github.com/codeversionmaster/cplusplus/blob/cplusplus17/lambda.cpp.

These are all the header files required for this program.

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;

The lambda expression is defined inside the main and is passed as the second argument to function sample_function. The lambda expression is a callable object or function object, meaning it can be passed like a function object to functions.

Here, func is the function object, and it will operate on each number when we call func(number). The argument passed from main function to func function is a lambda expression.

void sample_function(const vector<int>& numbers, const function<void(int)>& func) {
    for (int number : numbers) {
        func(number);
    }
}

The main function starts here. A vector of 5 unsorted numbers is initialized here.

printnum gets a function object out of lambda expression – [](int number) { //body of code }[] means there are no variables required from the surrounding context. It takes number as an int argument and does cout on the number variable.

When we use printnum(21), the lambda expression will act like a function as described above.

int main() {
    vector<int> numbers = {3, 2, 4, 1, 5};

    // 1. As a function object
    auto printnum = [](int number) { cout << number << " "; };
    printnum(21);
    cout << endl;

A lambda expression being a function object, is passed as the second argument to the function sample_function. As we have seen earlier, sample_function would use it and make it act in a loop on the numbers vector.

multiplier is specified in [], meaning it is variable from the surrounding context. It is available for use within the lambda expression.

    // 2. As an argument for another function, also taking variables from surrounding
    int multiplier = 2;
    sample_function(numbers, [multiplier](int number) { cout << number * multiplier << " "; });
    cout << endl;

Here, the STL algorithm sort is used. The third argument can be a comparator function. A simple lambda expression is passed as a function object instead of a callable and named function.


    // 3. Using as comparator in STL algorithms
    sort(numbers.begin(), numbers.end(), [](int a, int b) { return a < b; });
    for (int number : numbers) {
        cout << number << " ";
    }
    cout << endl;

    return 0;
}

You can compile and run the program as shown. We used -std=c++11 to check it is indeed supported by C++ 11.

$ g++ -std=c++11 -o lambda lambda.cpp 
$ ./lambda 
21 
6 4 8 2 10 
1 2 3 4 5