Lambda Expression in C++11

Introduction:

"A lambda expression, sometimes also referred to as a lambda function or (strictly speaking incorrectly, but colloquially) as a lambda, is a simplified notation for defining and using an anonymous function object. Instead of defining a named class with an operator(), later making an object of that class, and finally invoking it, we can use a shorthand."
Bjarne Stroustrup

A lambda function is an inline, anonymous function. The C++ concept of a lambda function originates in the lambda calculus and functional programming. Lambda expressions are typically used to encapsulate algorithms so that they can be passed to another function.



For example, this can be cleaner to read (it keeps everything in one place) and potentially simpler to maintain.

void func(std::vector<T>& v) {

  std::for_each(v.begin(), v.end(), [](int) { /* do something here*/ });

}

Lambda functions are just syntactic sugar for anonymous functions.

Syntax:

The syntax for the lambda expression is given below:


You can capture by both reference and value, which you can specify using & and = respectively:

  • [&nCnt] capture by reference
  • [&] captures all variables used in the lambda by reference
  • [=] captures all variables used in the lambda by value
  • [&, nCnt] captures variables like with [&], but nCnt by value
  • [=, &nCnt] captures variables like with [=], but nCnt by reference

The return type can be omitted, If lambda has only one return statement and it has the implicit type of decltype (return_statement). If a lambda is marked mutable (e.g. []() mutable { }) it is allowed to mutate the values that have been captured by value.

In simple cases, the will deduct the return type of the lambda function. However when you start to write more complex lambda you will quickly encounter cases where the return type cannot be deduced by the compiler. To resolve this you are allowed to explicitly specify a return type for a lambda function, using -> T.

Example:

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

void func(vector<double> &v, const double& nCnt){

    std::transform(v.begin(), v.end(), v.begin(),

        [nCnt](double d) -> double {

            if (d < nCnt) {
                return 0;
            } else {
                return d;
            }
        });
}

int main(int argc, char *argv[]) {

    std::cout << "Lambda Demo\n";
    double d = 5.0;
    vector<double> v = { 5, -7, 20, -22.4, 3, 45, -80, 55 };

    func(v, d);

    double data;
    foreach (data, v) {
        std::cout << data << " ";
    }
    std::cout <<"\n";
    return 0;
}

Note: Lambda expression has been extended and improved by various proposals in C++14 and C++17. We will discuss these features in another article.

Further References:


1. http://www.stroustrup.com/C++11FAQ.html#lambda
2. http://en.cppreference.com/w/cpp/language/lambda