2013-11-02 3 views
0

Я пытаюсь написать функцию для печати std-списка в C++. Верно ли, что для функции шаблона T нельзя использовать в качестве аргумента шаблона?Использовать typename как аргумент шаблона

template <typename T> 
void printlist(list<T> a) 
{ 
    list<T>::iterator i; 
    for (i=a.begin(); i!=a.end(); ++i) 
     cout<<*i<<" "; 
} 
+1

Я не уверен, но вы пытались его построить? – hamon

+1

Я не уверен, что именно вы имеете в виду, но вам нужно 'typename' перед' list :: iterator', а потом все хорошо. – jrok

+1

http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords –

ответ

4

Похоже, вы используете стандарты C++ 03, где для того, чтобы разобрать на C++ программа, компилятор должен знать для некоторых имен ли они имена типы или не-типы.

Как исправить вашу проблему вам нужно добавить typenamelist<T>::iterator перед тем, чтобы сделать его работу

template <typename T> 
void printlist(list<T> a) 
{ 
    typename list<T>::iterator i; 
    for (i=a.begin(); i!=a.end(); ++i) 
     cout << *i << " "; 
} 
+2

Это также относится к C++ 11. – juanchopanza

-2

Вы уверены, что имя шаблона list является разрешающие std::list?

EDIT: вы забыли ключевое слово typename. Сообщение об ошибке компилятора почти всегда говорит «typename, требуемое для зависимых типов». Это подчеркивает необходимость включения сообщений об ошибках при отправке сообщений о проблемах.

Другие отзывы:

  • Это не хорошая практика, чтобы построить итератор, как я, а затем инициализировать его позже. Лучше написать list<T>::iterator i = a.begin(); Это может быть часть вашего цикла for.
  • Вы можете использовать const_iterator
  • Вы передаете список по значению, а не по ссылке const. Другими словами, это заявление было бы лучше: void printlist(const std::list<T>& a)
+0

Код не в порядке. См. Другие ответы, которые почти правильны. – juanchopanza

4

Код в основном легальными. Некоторые компиляторы могут принимать это ... однако, писать его следующим образом обязательно работать (если у вас есть using namespace std определено):

template <typename T> 
void printlist(list<T> a) 
{ 
    typename list<T>::iterator i; 
    for (i=a.begin(); i!=a.end(); ++i) 
     cout<<*i<<" "; 
} 

Для повышения эффективности, вы должны пройти в списке в качестве константной ссылке:

template <typename T> 
void printlist(const list<T>& a) 
{ 
    typename list<T>::const_iterator i; 
    for (i=a.begin(); i!=a.end(); ++i) 
     cout<<*i<<" "; 
} 

Однако существует алгоритм STL, который уже делает это за вас. Предполагая, что вы хотите распечатать список целых чисел, просто написать:

copy(a.begin(), a.end(), ostream_iterator<int>(cout, " ")); 

Просто замените int с соответствующим типом элемента. Примечание. Этот алгоритм работает в любой последовательности.

+0

@ BЈовић: код «pass by value» компилируется просто отлично ... но он будет вызывать конструктор копирования, что может быть дорогостоящим. Использование ссылки const предотвращает создание копии. – MarkB

+0

Это «в основном законно» означает, что оно незаконно. – juanchopanza

+0

@juanchopanza: Он будет компилироваться на Visual Studio 2010. – MarkB

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