Solarian Programmer

My programming ramblings

C++11 lambda tutorial

Posted on November 1, 2011 by Sol

This article was updated in 28 August 2014

Don’t forget to check my short introduction to generic lambdas for C++14.

In my previous tutorials I’ve presented some of the newest C++11 additions to the language: regular expressions and raw strings. Another useful language addition is lambda, a lambda expression allows you to define and use anonymous functions inline (functions with a body but without a name). You can use a lambda expression instead of a function object, avoiding the need to create a separate class and a function definition. This is useful for example when you need a one-line expression to interact with many of the STL algorithms.

Lambda expressions are currently available in all major C++ compilers GCC, Visual Studio and Clang.

Let’s create a (useless) simple example of lambda expression that will return a number:

1 []() -> int { return 4; }();

Obviously the above code will do nothing visible (actually it will return an integer), we can use it to print 4 on the console:

1 int result = []() -> int { return 4; }();
2 cout << result << endl;

A slightly more useful example that will receive as input an integer and will return twice this number:

1 int result = [](int input) -> int { return 2 * input; }(10);
2 cout << result << endl;

From the above examples the syntax of a lambda expression can be written (this is not the complete syntax of a lambda expression):

1 [](input_paramter_declaration)->returned_type {body_of_the_lambda_expression}(parameters)

A lambda expression that will add two numbers and will return the result can be written as:

1 int result = [](int a,int b) -> int { return a + b; }(2,4);
2 cout << result << endl;

We can use a lambda expression inside another lambda expression, combining the above examples we can create a slightly more complex example:

1 int result = [](int m, int n) -> int { return m + n; } ([](int a) -> int { return a; }(2),[](int a) -> int { return a; }(3));
2 cout << result << endl;

If you need to use more than once a lambda expression it could be cumbersome to copy the same piece of code, you can use a pointer to the lambda expression:

1 auto func = [](int a, int b) -> int { return a+b; };
2 cout << func(2, 3) << endl;

The auto keyword will take care to define func as a pointer to the lambda expression.

Suppose we need to sort a vector of integers, using the sort algorithm from C++98 this can be implemented:

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 
 5 bool compare(int i,int j){return (i>j);}
 6 
 7 using namespace std;
 8 
 9 int main()
10 {
11 	int n = 10;
12 	vector<int> v(n);
13 	//initialize the vector with values from 10 to 1
14 	for(int i = n - 1, j = 0; i >= 0; i--, j++) v[j] = i + 1;
15 	//print the unsorted vector
16 	for(int i = 0; i < n; i++) cout << v[i] << " "; cout << endl;
17 	//sort the vector
18 	sort(v.begin(), v.end(), compare);
19 	//print the sorted vector
20 	for(int i = 0; i < n; i++) cout << v[i] << " "; cout << endl;
21 
22 	return 0;
23 }

Using a lambda expression we can achieve the same result by avoiding to declare a compare function:

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 
 5 using namespace std;
 6 
 7 int main()
 8 {
 9 	int n=10;
10 	vector<int> v(n);
11 	//initialize the vector with values from 10 to 1
12 	for(int i = n - 1, j = 0; i >= 0; i--, j++) v[j] = i + 1;
13 	//print the unsorted vector
14 	for(int i = 0; i < n; i++) cout << v[i] << " "; cout << endl;
15 	//sort the vector
16 	sort(v.begin(),v.end(),[](int i, int j) -> bool{ return (i < j);});
17 	//print the sorted vector
18 	for(int i = 0; i < n; i++) cout << v[i] << " "; cout << endl;
19 
20 	return 0;
21 }

If you are interested in learning more about the new C++11 syntax I would recommend reading Professional C++ by M. Gregoire, N. A. Solter, S. J. Kleper 2nd edition:

or, if you are a C++ beginner you could read C++ Primer (5th Edition) by S. B. Lippman, J. Lajoie, B. E. Moo.

comments powered by Disqus