2016-12-01 4 views
0

Я работаю над проблемой на тему итераторов STL, вопрос заключается в следующем: создает функцию Sum(), которая вычисляет сумму между двумя итераторами.Как использовать 2 итератора для вычисления суммы функции <строка, двойная>

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; 
} 

ниже, Что в мой основной():

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; 

он выдаст ошибку, говоря об ошибке C2768: 'Сумма': незаконное использование явных аргументов шаблона

Что пошло не так?

ответ

0

Это должно быть вместо этого:

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

Примечание, если вам нужно вычислить для map <string, double>, как вы заявили, вы не должны использовать шаблон, вы можете указать конкретные типы.

+0

Справедливо, что параметры шаблона не могут быть выведены здесь, поэтому 'const_iterator' должен быть явно передан. Наивная передача в' begin() 'и' end() 'из изменчивой карты будет терпеть неудачу. –

+0

@SamVarshavchik Вы правы, исправлены – Slava

0

Специфическая ошибка, что у вас есть то, что вы не должны указать аргументы шаблона снова прямо рядом с именем функции в своем заявлении:

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

Если вы удалили выделенную часть, вы получите следующий проблема, которая является то, что вы принимаете две карты вместо их итераторы:

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; 
} 

Примечание: внутренняя переменная не нужна, как вы должны принять итераторы копией.

Это, однако, не идиоматический код: это действительно многословные и предотвращает прохождение в итераторах над std::unordered_map или std::multimap (к примеру).

Вместо этого вы можете просто пойти на один уровень выше, и использовать тип итератора себя в качестве аргумента шаблона:

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

Наконец, тип результата функции Sum не подходит для карт, содержащих int64_t для пример. Вместо этого вы можете использовать внутренний value_type итератора, чтобы добраться до типа ... но это многословное, и вместо того, чтобы с помощью decltype обычно проще:

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; 
} 

Таким образом, когда вы добавляете целые числа, вы получите целое назад ,