作爲熱身到我的完整的答案,考慮以下因素:
template <typename T> void IterateOverContainer(T container) {
/* Error! */
T::iterator itr(container.begin());
}
這裏,iterator
是嵌套的T
內部的類型;例如,std::vector<int>::iterator
。爲了避免歧義這裏,typename
關鍵字成爲必要:
template <typename T> void IterateOverContainer(T container) {
/* Now good! */
typename T::iterator itr(container.begin());
}
現在,這是「明確」一類的名稱(這是typename
手段!),所以很明顯,我們要聲明一個變量,而不是通話一個函數。
這就是說,新的C++ 11層的功能,你可以用auto
完全迴避這個問題:
template <typename T> void IterateOverContainer(T container) {
auto itr(container.begin());
}
,或者更明確:
template <typename T> void IterateOverContainer(T container) {
auto itr = container.begin();
}
現在,你的問題:如何可以T::x(y)
曾經聲明一個變量?好了,由於到C的一個奇怪的怪癖,這是一個完全合法的變量聲明:
int (x);
這是一樣
int x;
因此,如果我們有這樣的事情:
template <typename T> void IterateOverContainer(T container) {
/* Error! */
T::iterator(itr);
}
這可以解釋爲T::iterator
類型的名爲itr
的變量的聲明,或者作爲對函數T::iterator
的呼叫通過itr
a是一個參數。 typename
的使用消除了它是哪一個。
有趣的是,這個額外括號的規定與Most Vexing Parse存在的原因相同。我希望你永遠不會遇到它。 :-)
希望這有助於!
看起來像你的帳戶是爲了回答這個問題:) – 2012-02-03 03:50:37
只是幾個簡單的問題,如果我在另一個內部定義一個類(x內部的Y)這將是類型Y :: x?我認爲小寫字母x是把我扔掉的東西,我沒有意識到這是一個嵌套類,如果它是什麼。也是T :: iterator itr(container.begin()); 構建一個類型,如何解釋? Sry因爲我對這個話題的無知 – rubixibuc 2012-02-03 03:53:00
@ rubixibuc-(請注意,在我收到這條消息之前,我已經更新了我的答案,所以你可能想閱讀結束我的編輯)。我不確定我是否通過「構建一個類型」來獲得你的意思。你能澄清嗎? – templatetypedef 2012-02-03 03:54:44