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 [1-3]. View Exercise #9: No for-loops to learn how to remove hand-written loops .

 

Note: std::for_each is supposed to be non-modifying [1], 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 <algorith>
#include <iostream>
#include <vector>

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 = static_cast<int>(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 <algorith>
#include <iostream>
#include <vector>

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

 

  1. Bjarne Stroustrup. The C++ Programming Language (3rd edition). ISBN: 0-201-88954-4. Chapter 18.12.1 : 'Prefer algorithms over loops'
  2. 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.'
  3. 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.

 

Valid XHTML 1.0 Strict