Question: I am working on a problem on topic of STL iterators, the question is that: **create a Sum() function that calculates the sum between two iterators.**

```
template<class T1, class T2 >
double Sum<T1,T2>(map<T1,T2>& start, map<T1,T2>&end)   
{
    double sum = 0.0;
   class map<T1,T2>::const_iterator i;
    for (i = start; i != end; ++i)
    {
        sum += i->second;
    } 
    return sum;
}

```

below is whats in my main(): 

```
map<string, double>::const_iterator map_StartIter =doubleMap.begin();   
map<string, double>::const_iterator map_EndIter = doubleMap.end();
cout<<"(2 iterator) map Sum is "<< Sum(map_StartIter,map_EndIter) << endl;

```

it throw an error saying error C2768: 'Sum' : illegal use of explicit template arguments 

What went wrong?

Answer: 
The specific error that you have is that you should NOT specify the template arguments again right next to the function name in its declaration:

```
template<class T1, class T2 >
double Sum<T1,T2>(map<T1,T2>& start, map<T1,T2>&end) 
          ^~~~~~~

```

If you removed the highlighted part, you will get to the next problem, which is that you are accepting two maps instead of their iterators:

```
template <class T1, class T2>
double Sum(typename std::map<T1, T2>::const_iterator it,
           typename std::map<T1, T2>::const_iterator end)
{
    double sum = 0.0;
    for (; it != end; ++it)
    {
        sum += it->second;
    } 
    return sum;
}

```

*Note: the inner variable is unnecessary as you should take iterators by copy.*

This is, however, non-idiomatic code: it's really verbose and prevents you from passing in iterators over a `std::unordered_map` or a `std::multimap` (for example).

Instead you can simply go one level higher, and use the *iterator type* itself as a template argument:

```
template <typename I>
double Sum(I it, I end)
{
    double sum = 0.0;
    for (; it != end; ++it)
    {
        sum += it->second;
    } 
    return sum;
}

```

Finally, the result type of the `Sum` function is not appropriate for maps containing `int64_t` for example. You can instead use the inner `value_type` of the iterator to get to the type... but it's verbose, and instead using `decltype` is generally simpler:

```
template <typename I>
auto Sum(I it, I end) -> decltype(it->second)
{
    decltype(it->second) sum = 0;
    for (; it != end; ++it)
    {
        sum += it->second;
    } 
    return sum;
}

```

This way, when you add integers, you get an integer back.
It should be this instead:

```
template<class Iter >
double Sum(Iter begin, Iter end)
{
     double sum = 0;
     for( Iter it = begin; it != end; ++it )
         sum += it->second;
     return sum;
}

```

Note if you need to calculate for `map <string, double>` as you stated, you do not have to use template, you can specify concrete types.