The sum must be initialized. We consider several options to do so.

## A neutral element? Time for maths?

What happens, if we call `sum2` for a vector of strings? The decisive spot is the initialization of `res`:

```template<typename Iterator>
typename value_type<Iterator>::result
sum2(Iterator  a, Iterator a_end)
{
typename value_type<Iterator>::result res = 0;
for(; a != a_end; ++a)
res += *a;
return res;
}
```

What should really happen, when we pass a sequence of `std::string` into `sum2`? The return value `res` should be initialized with an empty string. An in general, `res` should be initialized with the neutral element with respect to the addition. For built-in number types, this is the value 0, and therefore `sum2` works for those types. Where do we get the correct value for initialization?

### Alternatives for initializing the sum

There are several possibilities:

1. We use a technique analogous to `value_type`
2. We introduce an additional argument `init` to pass the neutral element
3. We initialize `res` with the first element of the sequence and start iteration with the second element

All these solutions have their pros and cons. The first solution requires some effort from the user, if "his" type is not yet supported. Also, there are types for which the correct value of the neutral element can only be determined at run time (for instance, a matrix type with dimensions determined at run time). We'll come back to this solution and extend it in a more general context.

Solution no. 2 complicates the interfaces, but permits to nest calls to `sum2`:

```x = sum(a.begin(), a.end(), sum(b.begin(), b.end(), init));
```

However, the problem is simply moved to a higher level: If the calling context is generic as well, it does not know the correct neutral element either. On the other hand, the implementation gets more general, because the type of `init` could be different from the iterator's value type (which is a danger as well, we'll discuss this below).

The 3rd solution keeps the simple interface, initializes automatically and correctly, and might be a bit more efficient. However, it does not work any more for empty sequences. This does not seem to be a big restriction, but if the function is used within a larger iteration computing partial sums of potentially empty sub-sequences, the ability to correctly deal with those could spare a lot of tests.

### A solution attempts for initialization

Lacking a clear winner, let's try to combine the strengths of the individual solutions. Solution no. 2 is certainly the most general, at the expense of being less comfortable to use. Thus, it seems natural to implement this as a basis and offer the other solutions later as convenience wrappers without the `init` argument. Here, we could also test at compile time, whether a neutral element is known, and then branch to either solution 1 or 3. Thus, the restriction of not being able to sum up empty sequences only applies when — lacking a neutral element — it does not make sense anyway.

Let's thus concentrate on solution 2 with the `init` argument:

```template<typename Iterator, typename T>
T
sum3(Iterator  a, Iterator a_end, T init)
{
T res = init;
for(; a != a_end; ++a)
res += *a;
return res;
}
```

### Next try with strings ...

Now, a call with a vector of string should be possible:

```std::string words[] = { "This", "is", "a", "sentence" };
// ...
std::string sentence = sum3(words, words+4, ""); // Ouch
```

Unfortunately, the compiler does not like this, because it determines the type of the literal `""` not as `std::string` but as `const char*`. Thus, we have to be a bit more specific:

```std::string sentence = sum3(words, words+4, std::string("")); // So!
```

Now it works! (Btw: Does the output in `sentence` look like you want it? And should we use `sum` for strings at all?)

Let's try what we can do with the additional parameter `init` ...