C++ Lambda Functions

C++11 adds the ability to create lambda functions, which are unnamed function objects. This provides a compact way to define functions at their point of use, without having to create a named function somewhere else. The following example creates a lambda that accepts two int arguments and returns their sum.

snippet
auto sum = [](int x, int y) -> int
{
return x + y;
};
cout << sum(2, 3); // "5"

Including the return type is optional if the compiler can deduce the return value from the lambda. In C++11 this required the lambda to contain just a single return statement, whereas C++14 extended return type deduction to any lambda function. Note that the arrow operator (->) is also omitted when leaving out the return type.

snippet
auto sum = [](int x, int y) { return x + y; };

C++11 requires lambda parameters to be declared with concrete types. This requirement was relaxed in C++14, allowing lambdas to use auto type deduction.

snippet
auto sum = [](auto x, auto y) { return x + y; };

Lambdas are typically used for specifying simple functions that are only referenced once, often by passing the function object as an argument to another function. This can be done using a function wrapper with a matching parameter list and return type, as in the following example.

snippet
#include <iostream>
#include <functional>
using namespace std;
void call(int arg, function<void(int)> func) {
func(arg);
}
int main() {
auto printSquare = [](int x) { cout << x*x; };
call(2, printSquare); // "4"
}

All lambdas start with a set of square brackets, called the capture clause. This clause specifies variables from the surrounding scope that can be used within the lambda body. This effectively passes additional arguments to the lambda, without the need to specify these in the parameter list of the function wrapper. The previous example can therefore be rewritten in the following way.

snippet
void call(function func) { func(); }
int main() {
int i = 2;
auto printSquare = [i]() { cout << i*i; };
call(printSquare); // "4"
}

The variable is here captured by value and so a copy is used within the lambda. Variables can also be captured by reference using the familiar ampersand prefix. Note that the lambda is here defined and called in the same statement.

snippet
int a = 1;
[&a](int x) { a += x; }(2);
cout << a; // "3"

It is possible to specify a default capture mode, to indicate how any unspecified variable used inside the lambda is to be captured. A [=] means the variables are captured by value and [&] captures them by reference. Variables captured by value are normally constant, but the mutable specifier can be used to allow such variables to be modified.

snippet
int a = 1, b = 1;
[&, b]() mutable { b++; a += b; }();
cout << a << b; // "31"

As of C++14, variables may also be initialized inside the capture clause. If there is no variable with the same name in the outer scope, the variable’s type will be deduced as if by auto.

snippet
int a = 1;
[&, b = 2]() { a += b; }();
cout << a; // "3"
Related Tutorial
Follow Us
https://www.facebook.com/Rookie-Nerd-638990322793530 https://twitter.com/RookieNerdTutor https://plus.google.com/b/117136517396468545840 #
Contents +