2015-12-11 2 views
-1
template<class T> 
map<T,int> counter(vector<T> a) 
{ 
    map<T,int> b; 
    pair<map<T,int>::iterator ,bool> pos; //This line shows compiler message 
    for(int i=0;i<a.size();++i) 
    { 
     pos=b.insert(make_pair(a[i],1)); 
     if(!(pos.second)) 
     { 
      b[pos.first -> first]++; 
     } 
    } 
    return b; 
} 

Это код с использованием шаблонов.Я хотел разработать функцию, которая принимает вектор любого типа и возвращает карту (аналогично счетчику в python)

map<int,int> counter(vector<int> a) 
{ 
    map<int,int> b; 
    pair<map<int,int>::iterator ,bool> pos; 
    for(int i=0;i<a.size();++i) 
    { 
     pos=b.insert(make_pair(a[i],1)); 
     if(!(pos.second)) 
     { 
      b[pos.first -> first]++; 
     } 
    } 
    return b; 
} 

Это функция, если я переписываю только целые числа. Целый код работает нормально, а первый - нет. Можете ли вы объяснить мне, почему это происходит, и как я могу его изменить, поэтому я работаю для каждого типа данных?

+1

Не видя, какие ошибки вы получаете (при размещении вопросов о ошибке сборки всегда включайте полный журнал сборки, полный и неотредактированный), но я предполагаю, что вы должны прочитать [Где и почему мне нужно поставить «шаблон» и Ключевые слова «typename»?] (Http://stackoverflow.com/questions/7923369/when-is-the-typename-keyword-necessary) –

ответ

0

map<T,int>::iterator - зависимое имя, то есть оно зависит от параметра шаблона. Вы должны сказать компилятор, что он всегда называет тип, так что он может быть разобран правильно:

pair<typename map<T,int>::iterator ,bool> pos; 
// ^^^^^^^^ 

См this question для получения дополнительной информации о typename ключевом слове, и когда вы должны использовать его.

2

Когда вы говорите, что «первый не работает нормально», вы подразумеваете, что он не компилируется из-за некоторой фанковой ошибки около iterator? Внутри шаблона зависимых имена должны быть помечено как виды использования typename:

pair<map<T, int>::iterator, bool> pos; 

iterator Имени вложенным имя внутри std::map<T, int>. Вы бы использовали только

pair<typename map<T, int>::iterator, bool> pos; 

вместо этого.

Лично я был бы склонен полностью боковым шагом вопроса орудия функции как это:

template<class T> 
std::map<T, int> counter(std::vector<T> const& a) 
{ 
    std::map<T, int> result; 
    std::for_each(a.begin(), a.end(), [&](T const& value){ ++result[value]; }); 
    return result; 
} 

Этой реализация использует тот факт, что operator[]() вставляет новые элементы со значением значения инициализации (т.е. с использованием T()). Иначе говоря, когда объект находится внутри карты, он вернет ссылку на нуль, инициализированный int.

Смежные вопросы