tags:

views:

290

answers:

5

I just read the code for std::for_each:

template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
  for ( ; first!=last; ++first ) f(*first);
  return f;
}

and could not see any good reasons for this template function to return the input function. Does anyone have any examples on where this would be useful?

+1  A: 

its useful if you want to save (and later use) the functor state between calls for example, count the number of elements in a collections or indicate some failure to process an element by setting some internal variable.

Alon
+16  A: 

It's to allow you to accrue state in your function and then return it to your calling code. For instance, your function (as a functor class) could have a member int for counting the number of times it had been called.

Here is a page with some examples : http://xenon.arcticus.com/c-morsels-std-for-each-functors-member-variables

Sam
Ofcourse, why didn't I think of this? Thx :)
larsm
I was told once upon a time here (by Charles Bailey, I think), that this behavior isn't guaranteed. I didn't believe him; I thought the standard, while unclear, mostly made sense in that context. (Why else would we get a function?) But just a warning, maybe this is just "standard" compiler behavior and not standard behavior.
GMan
@GMan: returning the function is required by the standard (§25.1.1/2).
Jerry Coffin
Don't forget `std::accumulate` in `<numeric>`, which allows you to maintain state outside the functor in this case.
Potatoswatter
That's also what I quoted, Jerry. I was told it could simply return a copy of the original function, apply a new copy of the function to each element, etc. I felt that was a poor argument, but that's what it was. In short, it'll return the function, but you aren't guaranteed how it was used. (Remember, not my argument, just curious.)
GMan
A: 

No particular reason I guess. What you can do though is using the returned function in another foreach call, thus avoiding writing the function name twice and possibly making a mistake there.

+1  A: 

If you pass in a function object, aka functor, and it has state, returning the function object allows you to access it's state after iterating the sequence. Let's say you had a function object that computes three different variables from the sequence and holds them in member variables. Each time the functor is called, you update the counters. If for_each didn't return the object, how would you get the result?

Note... this is why you must always implement copy-construction, and assignment for function objects with state.

Jeff Paquette
You don't HAVE TO implement the copy constructor or the assignment operator for a functor, any more than you do for any other class - the defaults will very likely do what is necessary.
anon
A: 

Returning the function basically makes std::for_each into a mediocre imitation of std::accumulate. It lets you accumulate something in the function/functor, and then retrieve that accumulated value when it's done. Almost any time you think this might be a useful thing to do, you should probably consider using std::accumulate instead.

Jerry Coffin