Online Book Reader

Home Category

Professional C__ - Marc Gregoire [236]

By Root 1240 0
for things like printing every element in a container. Following is an example using a lambda expression and uniform initialization, printing the elements from the map:

map myMap = {{4, 40}, {5, 50}, {6, 60}};

for_each(myMap.cbegin(), myMap.cend(), [](const pair& p)

{cout << p.first << "->" << p.second << endl;});

Code snippet from NonModifyingAlgorithms\ForEachBasicLambda.cpp

The output is as follows:

4->40

5->50

6->60

Doing the same thing in pre-C++11 requires a separate function, and a pointer to it is given to for_each():

void printPair(const pair& elem)

{

cout << elem.first << "->" << elem.second << endl;

}

int main()

{

map myMap;

myMap.insert(make_pair(4, 40));

myMap.insert(make_pair(5, 50));

myMap.insert(make_pair(6, 60));

for_each(myMap.begin(), myMap.end(), printPair);

return 0;

}

Code snippet from NonModifyingAlgorithms\ForEachBasic.cpp

A functor could be useful in the context of for_each() because for_each() returns a copy of the callback object, so you can accumulate information in your functor that you can retrieve after for_each() has finished processing each element. For example, you could calculate both the sum and product of elements in one pass by writing a functor SumAndProd that tracks both at the same time:

// The populateContainer() function is identical to the one shown earlier

// for comparison algorithms, so it is omitted here.

class SumAndProd : public unary_function

{

public:

SumAndProd() : sum(0), prod(1) {}

void operator()(int elem);

// make sum and prod public for easy access

int sum;

int prod;

};

void SumAndProd::operator()(int elem)

{

sum += elem;

prod *= elem;

}

int main()

{

vector myVector;

populateContainer(myVector);

SumAndProd func;

func = for_each(myVector.cbegin(), myVector.cend(), func);

cout << "The sum is " << func.sum << endl;

cout << "The product is " << func.prod << endl;

return 0;

}

Code snippet from NonModifyingAlgorithms\SumAndProd.cpp

You might be tempted to ignore the return value of for_each(), yet still try to read information from func after the call. However, that doesn’t work because func is passed-by-value into for_each(), so for_each() receives a copy of func. You must capture the return value in order to ensure correct behavior.

To show the power of C++11 lambda expressions, the preceding example using a functor to calculate the sum and product of a range can be modified to use a small lambda expression as follows. Note that the lambda expression captures all variables in its enclosing scope by reference with [&], otherwise changes made to sum and prod in the lambda expression would not be visible outside the lambda:

// The populateContainer() function is identical to the one shown earlier

// for comparison algorithms, so it is omitted here.

vector myVector;

populateContainer(myVector);

int sum = 0;

int prod = 1;

for_each(myVector.cbegin(), myVector.cend(),

[&](int i){

sum += i;

prod *= i;

});

cout << "The sum is " << sum << endl;

cout << "The product is " << prod << endl;

Code snippet from NonModifyingAlgorithms\SumAndProdLambda.cpp

A final point about for_each() is that your lambda or callback is allowed to take its argument by reference and modify it. That has the effect of changing values in the actual iterator range. The voter registration example later in this chapter shows a use of this capability.

Modifying Algorithms

The STL provides a variety of modifying algorithms that perform tasks such as copying elements from one range to another, removing elements, or reversing the order of elements in a range.

The modifying algorithms all have the concept of source and destination ranges. The elements are read from the source range and added to or modified in the destination range. The source and destination ranges can often be the same, in which case the algorithm is said to operate in place.

Ranges from maps and multimaps cannot be used as destinations of modifying algorithms. These algorithms overwrite entire elements, which

Return Main Page Previous Page Next Page

®Online Book Reader