從註釋擴展:
拿這個程序爲例:
template <typename T>
struct S1 { struct I { }; };
template <typename T>
struct S2 { typedef struct S1<T>::I I; }; // okay
template <typename T>
struct S3 { typedef struct S2<T>::I I; }; // okay at definition time
// usually error at instantiation time
template <>
struct S2<short> : S1<short> { };
int main() {
S1<int>::I a;
S2<int>::I &b = a; // okay
S3<int>::I &c = b; // error
S1<short>::I d;
S2<short>::I &e = d; // okay
S3<short>::I &f = e; // okay
}
在模板定義時,既S2
和S3
都還好:14.6p5列出在不需要typename
例外。基本上:在使用是明確的,因爲名稱永遠不能是除類型以外的其他名稱,typename
不是必需的。這包括typename
在句法上不允許的幾種情況,所以在需要typename
時意味着無法編寫程序。 typename struct S<T>::I
和struct typename S<T>::I
都是硬錯誤,並且struct S<T>::I
是明確的。
在模板實例化時,的3.4.4規則是更清楚:既struct S1<int>::I
和struct S2<int>::I
然後可以發現,其中,很明顯,S2<int>::I
是一個typedef,所以struct S2<int>::I
是錯誤的。同時,在那個時候,S2<short>::I
看起來不是typedef,而是一個結構,所以struct S2<short>::I
被允許。
來源
2014-02-22 10:46:32
hvd
我不明白爲什麼它會是一個問題,如果它是類型依賴的,只要查找發生在實例化點。這是clang實現的,這就是爲什麼它允許'struct S1 :: I'然後診斷'struct S2 :: I'作爲http://ideone.com/paV3Kh中的錯誤(注意:ideone使用GCC,並且GCC允許這樣做,所以你沒有看到那裏的錯誤) –
hvd
@ hvd有趣,奇怪;謝謝!但真正想知道的是爲什麼'typename'關鍵字不是必需的。其實我還沒有查找那些不需要的例外列表,所以我現在就去做... – Potatoswatter
好點。引用14。6p2:「假定模板聲明或定義中使用的名稱取決於* template-parameter *,則不會爲類型命名,除非可用的名稱查找找到類型名稱或名稱符合關鍵字'typename的 '「。我沒有看到允許'struct S1 :: I'的異常。 –
hvd