2013-11-02 56 views
0

我想寫一個函數來打印C++中的std列表。對於模板函數,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

我不確定你的意思是什麼,但是你需要'list :: iterator'之前的'typename',然後一切都很好。 – jrok

+1

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

回答

4

好像你正在使用C++ 03的標準,其中,以解析C++程序,編譯器需要知道某些他們的名稱是否類型非類型

作爲修復您的問題,您需要list<T>::iterator之前添加typename,使其工作

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

編輯:你忘了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<<" "; 
} 

爲了提高效率,你應該通過在列表中的const引用:

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Јовић:'傳值'代碼編譯得很好......但是,它會調用複製構造函數,這可能很昂貴。使用const引用可防止複製構造。 – MarkB

+0

它「大部分是合法的」意味着它是非法的。 – juanchopanza

+0

@juanchopanza:它將在Visual Studio 2010上編譯。 – MarkB