Online Book Reader

Home Category

Professional C__ - Marc Gregoire [226]

By Root 1521 0
clause, [], then the variable value would not be available in the body of the lambda expression. The lambda expression returns the result of performing the comparison i>value, which causes the compiler to automatically make the return type of the lambda a Boolean value. Note that the example initializes the vector using C++11 uniform initialization, discussed in Chapter 9.

vector vec = {1,2,3,4,5,6,7,8,9};

int value = 3;

int cnt = count_if(vec.cbegin(),vec.cend(),

[=](int i){return i>value;});

cout << "Found " << cnt << " values > " << value << endl;

Code snippet from Lambdas\count_if.cpp

The output is as follows:

Found 6 values > 3

The preceding example can be extended to demonstrate capturing variables by reference. The following lambda expression will count the number of times it was called by incrementing a variable in the enclosing scope that was captured by reference.

vector vec = {1,2,3,4,5,6,7,8,9};

int value = 3;

int cntLambdaCalled = 0;

int cnt = count_if(vec.cbegin(),vec.cend(),

[=, &cntLambdaCalled](int i){++cntLambdaCalled; return i>value;});

cout << "The lambda expression was called " << cntLambdaCalled

<< " times." << endl;

cout << "Found " << cnt << " values > " << value << endl;

Code snippet from Lambdas\count_if_ref.cpp

The output is as follows:

The lambda expression was called 9 times.

Found 6 values > 3

generate

The generate() algorithm allows you to fill an iterator range with certain values. The following example uses the generate() algorithm together with a lambda expression to put the numbers 2, 4, 8, 16, and so on in the vector.

vector vec(10);

int value = 1;

generate(vec.begin(), vec.end(), [&value]{value*=2; return value;});

for (auto& i : vec)

cout << i << " ";

Code snippet from Lambdas\generate.cpp

The output is as follows:

2 4 8 16 32 64 128 256 512 1024

for_each

The for_each() algorithm can be used to perform a specific action on all elements in the given range. A simple example is to use the for_each() algorithm in combination with a lambda expression to print values from a vector. This example defines a vector of integers. The first two arguments to for_each() specify the range in the container on which to apply the lambda expression given as third argument. For each value in the given range, the for_each() algorithm will call the lambda expression and will pass that value as argument to the lambda expression. Since the vector holds integers, the parameter for the lambda expression is an int.

vector vec = {11,22,33,44};

int index = 0;

for_each(vec.begin(), vec.end(),

[&index](int i){cout << "Value " << (index++)

<< ": " << i << endl;});

Code snippet from Lambdas\for_each.cpp

The output of the preceding code is as follows:

Value 0: 11

Value 1: 22

Value 2: 33

Value 3: 44

FUNCTION OBJECTS


You can overload the function call operator in a class such that objects of the class can be used in place of function pointers. These objects are called function objects, or just functors.

Many of the STL algorithms, such as find_if() and the second form of accumulate(), require a function pointer as one of the parameters. When you use these functions, you can pass a functor instead of a lambda or function pointer. C++ provides several predefined functor classes, defined in the header file, that perform the most commonly used callback operations.

Functor classes often consist of simple one-line expressions. The clumsiness of having to create a function or functor class, give it a name that does not conflict with other names, and then use this name is considerable intellectual overhead for what is fundamentally a simple concept. In these cases, using anonymous (unnamed) functions represented by lambda expressions is a big convenience. Their syntax is easier and can make your code easier to understand. They are discussed in the previous sections. However, this section explains functors and how to use the predefined functor classes because you will likely encounter them at some point.

With C++11, it is recommended

Return Main Page Previous Page Next Page

®Online Book Reader