I want to know why
int sum = accumulate(V.begin(), V.end(), 0);
// sum == 6
sum = 0; // 0 - value of 3rd param
for (auto x : V) sum += x;
int product = accumulate(V.begin(), V.end(), 1, multiplies<int>());
int sum = accumulate(V.begin()+1, V.end(), V.begin());
The way things are, it is annoying for code that knows for sure a range isn't empty and that wants to start accumulating from the first element of the range on. Depending on the operation that is used to accumulate with, it's not always obvious what the 'zero' value to use is.
If on the other hand you only provide a version that requires non-empty ranges, it's annoying for callers that don't know for sure that their ranges aren't empty. An additional burden is put on them.
One perspective is that the best of both worlds is of course to provide both functionality. As an example, Haskell provides both
foldr1 (which require non-empty lists) alongside
foldr (which mirror
Another perspective is that since the one can be implemented in terms of the other with a trivial transformation (as you've demonstrated:
std::transform(std::next(b), e, *b, f) --
std::next is C++11 but the point still stands), it is preferable to make the interface as minimal as it can be with no real loss of expressive power.