The arithmetic operation can be parameterized as well.The resulting generic reduction is analoguous to std::accumulate.

Why only add?

We move in space with minimum waste and maximum joy. [...]
No need to ask, he's a Smooth operator, smooth operator, smooth operator, smooth operator.
Sade Adu (from the song Smooth Operator)

We have seen how to implement a generic sum. If we want to compute the maximum of a sequence, we know what to do:

template<typename Iterator, typename T>
T
max(Iterator  a, Iterator a_end, value<T> init)
{
  T res = init;
  for(; a != a_end; ++a)
    res = std::max(res, *a);
  return res;
}

Stop, Stop, STOP!

Can't we achieve this in a simpler way? We can see that max is structurally identical to sum. Except the line computing the maximum of two operands instead of their sum. By consequence, if we parametrize this operation as well, we obtain a generic function which can do both (and much more ...).

template<typename Iterator, typename T, typename BinOp>
T reduce(Iterator begin, Iterator end, value<T> init, BinOp op)
{
  T res = init;
  for(; begin != end; ++begin)
    res = op(res,*begin);
  return res;
}

Using reduce

We get back our sum, when we pass the built-in addition operator to reduce:

double a[N] = { ... };
double suma = reduce(a, a+N, 0.0, std::plus<double>());

The only difference to our sum implementations is, that now res = res + *begin is called instead of res += *begin. For built-in types the compiler should produce identical code, but for user-defined types this can be a performance loss. This is a topic for a different article.

Of course, products can be computed in exactly the same way:

matrix4 pose = reduce(matrices.begin(), matrices.end(), matrix4::unit(), std::multiplies<matrix4>());

For computing the maximum, we should be able to use std::max ...? Yes, but with the difference that std::max is a function template and std::plus is a class template, thus the syntax is slightly different:

double a[N] = { ... };
double maxa = reduce(a, a+N, ???, std::max<double>);

Um ... what about init? Is there a neutral element for maximum? Times stay interesting ...