2012-04-13 2 views
0

Я понимаю, что есть много похожих вопросов, но я не мог найти решение, которое решает мою проблему (читайте: я не понял по-настоящему ответы, чтобы я мог применить его в моем случае)templated function с аргументом, который является шаблоном класса

у меня есть следующие функции:

void printVariable(map<string, bool*>::iterator it) 
{ 
    cout << it->first << " " << *(it->second) << endl; 
} 

Теперь если у меня есть map<string, bool*> mapping я могу сделать следующее: printVariable(mapping.begin());

Это работает, теперь у меня есть аа map<string, int*> и хочу быть в состоянии сделать то же самое, поэтому я решил изменить printVariable функции:

template <typename T> 
void printVariable(map<string, T*>::iterator it) 
{ 
    cout << it->first << " " << *(it->second) << endl; 
} 

Однако это дает ошибку компиляции (ССАГПЗ):

error: variable or field 'printVariable' declared void 
error: expected ')' before 'it' 

Я думаю, я могу обойти эту проблему довольно легко при перегрузке функции. Но я хотел бы знать, почему это не работает.

Edit2: удален текст претендуя на правильном решение было неправильным

+0

Нужно добавить спецификатор typename к параметру, поскольку итератор является зависимым типом в типе шаблона? 'void printVariable (typename map :: iterator it)' –

ответ

5

Вы должны сказать typename к неоднозначности зависимого имени:

template <typename T> 
void printVariable(typename map<string, T*>::iterator it) 
//     ^^^^^^^^ 

Однако, обратите внимание, что это не выводим контекст, так что эта форма не очень удобно.

еще лучше, просто сделать весь итератор параметр шаблона:

template <typename Iter> 
void printVariable(Iter it) 
{ /* ... */ } 

Таким образом, вы также захватить карты с нестандартными компараторов или распределителей, а неупорядоченные карты и т.д. и т.п.


Вот простой мысленный эксперимент, почему у вас нет выведенного контекста в первой ситуации: Как следует вывести T по следующему вызову foo?

template <typename T> void foo(typename Bar<T>::type); 

template <typename T> struct Bar { typedef char type; }; 
template <> struct Bar<int>  { typedef int type; }; 
template <> struct Bar<double> { typedef int type; }; 

foo(10); // What is T? 
+0

Нет, первый вариант не работает. –

+0

Первый вариант не работает (думаю, я уже пробовал это). Второй вариант действительно работает! Чувствуешь себя глупым, чтобы не переваривать что-то подобное, чтобы попробовать :) – user1302914

+0

Может кто-нибудь объяснить, почему первый вариант не работает? Я действительно предпочитаю этот вариант (если он должен работать), потому что тогда сигнатура функции намного понятна в отношении того, что должен быть аргументом функции (или я не должен рассматривать такую ​​вещь?) – user1302914

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