Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

( C++ ) std::for_each

 

Algorithm to perform a non-modifying function on the elements of a sequence (on a std::vector, for example). Use std::transform to perform modifying functions on the elements of a sequence.

 

Prefer algorithms over hand-written loops [0] [1] [2] . View Exercise #9: No for-loops to learn how to remove hand-written loops .

 

Note : std::for_each is supposed to be non-modifying ([0] ), but I use it for modifying my sequences anyway).

 

There are two kinds of examples below. The first uses std::for_each combined with simple functions.

 

The second piece of code shows the use of functors for more advanced functionality. It is advised to use the latter [3], but I will show the first as an example. There are also STL functors.

 

Example: Use of plain functions

 

 

#include <iostream>

#include <vector>

#include <algorith>

 

void SetToOne(int& i)

{

i = 1;

}

 

void MultiplyByTwo(int& i)

{

i*=2;

}

 

void SetToRandom(int& i)

{

i = std::rand()%10;

}

 

void CoutVector(const std::vector<int>& myVector)

{

const int size = myVector.size();

for (int i=0; i!=size; ++i)

{

std::cout << i << " : " << myVector[i] << std::endl;

}

}

 

int main()

{

const int size = 5;

std::vector<int> myVector(size);

std::for_each(myVector.begin(),myVector.end(), SetToOne);

CoutVector(myVector);

std::for_each(myVector.begin(),myVector.end(), MultiplyByTwo);

CoutVector(myVector);

std::for_each(myVector.begin(),myVector.end(), SetToRandom);

CoutVector(myVector);

std::for_each(myVector.begin(),myVector.end(), MultiplyByTwo);

CoutVector(myVector);

}

 

 

Example: Use of non-STL functors

 

 

 

#include <iostream>

#include <vector>

#include <algorith>

 

struct MyInitializer

{

MyInitializer()

: index(0) {}

 

template<class T>

void operator () (T & a)

{

a = index;

++index;

}

private:

int index;

 

};

 

struct MyIndexCout

{

MyIndexCout() : index(0) {}

template<class T>

void operator () (const T & a)

{

std::cout << index << " : " << a << std::endl;

++index;

}

private:

int index;

};

 

struct MySquarer

{

template<class T> void operator () (T & a)

{

a*=a;

}

};

 

int main()

{

const int size = 10;

std::vector<int> myVector(size);

std::for_each(myVector.begin(), myVector.end(), MyInitializer());

std::for_each(myVector.begin(), myVector.end(), MyIndexCout());

std::cout << "-----------" << std::endl;

std::for_each(myVector.begin(), myVector.end(), MySquarer());

std::for_each(myVector.begin(), myVector.end(), MyIndexCout());

}

 

 

 

 

References

[0]          Bjarne Stroustrup. The C++ Programming Language (3rd edition). ISBN: 0-201-88954-4. Chapter 18.12.1 : 'Prefer algorithms over loops'

[1]          Herb Sutter and Andrei Alexandrescu. C++ coding standards: 101 rules, guidelines, and best practices. ISBN: 0-32-111358-6. Chapter 84: 'Prefer algorithm calls to handwritten loops.'

[2]          Herb Sutter and Andrei Alexandrescu. C++ coding standards: 101 rules, guidelines, and best practices. ISBN: 0-32-111358-6. Chapter 88: 'Prefer function objects over functions as algorithm and comparer arguments.'

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.