2011-03-04 92 views
18

我正試圖學習STL庫,並遇到一個奇怪的問題。此代碼編譯完美:關於模板函數中向量迭代器的問題

void Show(vector<int> myvec) 
{ 
    vector<int>::iterator it; 
    cout << "Vector contains:"; 
    for(it = myvec.begin(); it < myvec.end(); it++) 
    { 
     cout << " " << *it; 
    } 
    cout << endl; 
} 

而這一次讓我在編譯時的錯誤消息:

template <class T> 
void Show2(vector<T> myvec) 
{ 
    vector<T>::iterator it; 
    cout << "Vector contains:"; 
    for(it = myvec.begin(); it < myvec.end(); it++) 
    { 
     cout << " " << *it; 
    } 
    cout << endl; 
} 

的錯誤是:

$ g++ hello.cpp 
hello.cpp: In function ‘void Show2(std::vector<T, std::allocator<_Tp1> >)’: 
hello.cpp:19: error: expected ‘;’ before ‘it’ 
hello.cpp:21: error: ‘it’ was not declared in this scope 

這似乎是一個很簡單的錯誤,但我找不到它。

+0

可能的重複[在哪裏放置「模板」和「typename」依賴名稱](http://stackoverflow.com/questions/610245/where-to-put-the-template-and-typename-依賴名稱) – fredoverflow

+2

可能回答了很多以前,但很難搜索typename /依賴名稱,如果你不知道這樣的條款存在 – Erik

+0

@FredOverflow這是一個非常不錯的鏈接,我可能會讀它馬上。但是,就像@Erik所說的,如果你不知道底層問題是什麼,那麼你會搜索許多特定的術語,而不會去解決更普遍的問題。我做了許多迭代器,模板,矢量,STL等搜索,沒有發現任何東西,我甚至都不知道關鍵字'typename'存在(:(是的,我是noob:P)。我認爲它只是一個愚蠢的語法錯誤 –

回答

24

你需要說typename vector<T>::iterator it

另一方面,您按值通過vector。這意味着整個vector被複制到函數調用中。 void Show(vector<T> const &myvec)和使用const_iterator會更明智。

+4

如果他傳遞了一個const引用,你還需要告訴他使用一個const_iterator。 – Erik

+0

@Erik:絕對正確,更新了我的文章。 –

+0

感謝您的提示。 –

2

某些編譯器在模板中檢測什麼是成員名稱和什麼是類型名稱時遇到問題。嘗試在你的模板函數體的第一行寫這樣的東西。

​​

+1

正確,但它不是一個真正的編譯器問題。 C++標準強制編譯器將模板中的依賴名稱視爲成員而不是類型,除非使用* typename *。 – decltype

+1

這不是「一些編譯器」。語法根本不允許。 「一些編譯器」可以通過重新使用類型名稱來重新猜測程序員,如果解析失敗沒有它,從而編譯*一些*不正確的情況。 –

+0

你說得對。採取點! – CygnusX1

0

也許它可以使用​​ 你的編譯器不能知道有一個內部類迭代器。

16

你需要這樣的:

typename vector<T>::iterator it; 

這告訴vector<T>::iterator應被視爲一種類型的編譯器,它的東西不能假設,因爲iterator取決於什麼T是。

0

在第一實例中的參數,儘管它使用一個模板,是不是一個模板,它是完全定義的類(vector<int>

在後者的實例中的參數是T型的模板,因此需要鍵入名稱