C++11 lambda tutorial

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.