C++14 lambda tutorial

The last iteration of C++, C++14 was approved this month. C++14 brings a few much anticipated changes to the C++11 standard, like allowing auto to be used as the return type of a function, or generic lambdas - the subject of this article.

Lambdas, in C++, were introduced by the C++11 standard. They were meant to let the coder write short, anonymous functions, that could be used instead of a function object, avoiding the need to create a separate class and a function definition. Here is a typical example of C++11 lambda usage, that returns the square of a number:

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

If you need to reuse the same piece of code in more than one place, you can save the function in a variable:

1 auto func = []( int input ) { return input * input ; }; 2 3 // first use 4 std :: cout << func ( 10 ) << std :: endl ; 5 6 // second use 7 std :: cout << func ( 23 ) << std :: endl ;

Can you see the problem with the above code ? It can be used only for integers. What if, we want to use the same lambda for a double or for a complex number ? Say that we want to be able to write something like this:

1 // square of an int 2 std :: cout << func ( 10 ) << std :: endl ; 3 4 // square of a double 5 std :: cout << func ( 2.345 ) << std :: endl ; 6 7 // square of a complex number 8 std :: cout << func ( std :: complex < double > ( 3 , - 2 )) << std :: endl ;

We could obviously use a function template:

1 template < typename T > 2 T func ( T z ) { 3 return z * z ; 4 }

However, this is not the solution we are looking for in the context of this article, the above is a named, global function,

The C++14 standard introduced the concept of generalized lambda, basically we are allowed to use auto for the parameter types of a lambda expression. We could write a shorter and, in a way, more elegant solution now:

1 auto func = []( auto input ) { return input * input ; };

Here is a complete program that exemplifies the above:

1 #include <iostream> 2 #include <complex> 3 4 int main () { 5 // Store a generalized lambda, that squares a number, in a variable 6 auto func = []( auto input ) { return input * input ; }; 7 8 // Usage examples: 9 // square of an int 10 std :: cout << func ( 10 ) << std :: endl ; 11 12 // square of a double 13 std :: cout << func ( 2.345 ) << std :: endl ; 14 15 // square of a complex number 16 std :: cout << func ( std :: complex < double > ( 3 , - 2 )) << std :: endl ; 17 18 return 0 ; 19 }

The above code can be compiled with any modern C++ compiler, like GCC 4.9.x or Clang. Here is the result of compiling and running the code with GCC and Clang on OS X:

1 $ clang++ -std = c++1y -pedantic -Wall -stdlib = libc++ test_01.cpp -o test_01 2 $ ./test_01 3 100 4 5.49903 5 (5,-12) 6 $ g++-4.9.1 -std = c++14 -pedantic -Wall test_01.cpp -o test_01 7 $ ./test_01 8 100 9 5.49903 10 (5,-12) 11 $

However, the generic lambda shines in combination with STL. Suppose that you want to sort a vector in decreasing order. Using a generic lambda, we can write:

1 std :: sort ( V . begin (), V . end (), []( auto i , auto j ) { return ( i > j ); });

Here is a complete example of sorting a vector, of ten integers, in decreasing order, using generic lambda and the STL:

1 #include <iostream> 2 #include <vector> 3 #include <numeric> 4 #include <algorithm> 5 6 int main () { 7 std :: vector < int > V ( 10 ); 8 9 // Use std::iota to create a sequence of integers 0, 1, ... 10 std :: iota ( V . begin (), V . end (), 1 ); 11 12 // Print the unsorted data using std::for_each and a lambda 13 std :: cout << "Original data" << std :: endl ; 14 std :: for_each ( V . begin (), V . end (), []( auto i ) { std :: cout << i << " " ; }); 15 std :: cout << std :: endl ; 16 17 // Sort the data using std::sort and a lambda 18 std :: sort ( V . begin (), V . end (), []( auto i , auto j ) { return ( i > j ); }); 19 20 // Print the sorted data using std::for_each and a lambda 21 std :: cout << "Sorted data" << std :: endl ; 22 std :: for_each ( V . begin (), V . end (), []( auto i ) { std :: cout << i << " " ; }); 23 std :: cout << std :: endl ; 24 25 return 0 ; 26 }

This is the result of running the above code on my machine:

1 $ g++-4.9.1 -std = c++14 -pedantic -Wall test_02.cpp -o test_02 2 $ ./test_02 3 Original data 4 1 2 3 4 5 6 7 8 9 10 5 Sorted data 6 10 9 8 7 6 5 4 3 2 1 7 $

If you are interested to learn more about the new C++11 syntax I would recommend reading The C++ Programming Language by Bjarne Stroustrup.

or, Professional C++ by M. Gregoire, N. A. Solter, S. J. Kleper: