Noeud:for_each, Noeud « Next »:, Noeud « Previous »:Introducing Generic Algorithms, Noeud « Up »:Generic Algorithms and Function Objects



for_each

The for_each algorithm, as you would expect, marches through some range performing some operation on each element as it goes. Sounds vague? That's because we can choose to do what we want for each element. We could march through a range printing the elements out; or modify the contents of each element.

In fact, for_each may sound familiar. It should be! We used a function earlier called with_each, in Function Objects - in a Nutshell. This may appear a bit cheaky, but we didn't actually know about generic algorithms when we were discussing function objects, and instead provided a quick-stub solution.

Let's look at the signature of for_each first:

UnaryProc for_each(InputIterator beg, InputIterator end, UnaryProc op)

As you can see, for_each takes two InputIterators, meaning that we can use any container or object that uses InputIterators. op is the key point to the algorithm. We use op, a unary function to operate on each element; it is a unary operator because it takes one argument; namely, the element under scrutiny - in almost all respects, it's exactly the same as with_each, with the difference that for_each is already defined for us. There is also a for_each algorithm that accepts a binary operation op. Let's look at a simple example.

     /* generic1.cc
      * Compiled using gcc generic1.cc Address.cc -o generic1 */
     #include <algorithm>
     #include <vector>
     #include "AddressRepository.hh"
     
     int main()
     {
       std::vector<Address> v;
       v.push_back(addr1);
       v.push_back(addr2);
       v.push_back(addr3);
       v.push_back(addr4);
       for_each(v.begin(), v.end(), mem_fun_ref(&Address::print));
     }
     
     Example 3.19: generic1.cc - printing out elements using for_each
     

It's pretty straightforward really - and looks strikingly similar to function4.cc from Function Adaptors, except that we don't need to define our own method to march through a range of elements because for_each does it for us (notice we utilise mem_fun_ref to pass the member function print to for_each). Comparing this with the earlier method of using pos->print() and using with_each, you'll agree that it's easy on the eyes if nothing else.