2014-02-22 183 views
1

我從來沒有在this question之前看到一個詳細類型說明符中的嵌套名稱說明符,並且乍一看我以爲它甚至沒有被語法。現在我看到,自從C++ 98到目前爲止,它被翻譯爲一種特殊情況,沒有類型名稱說明符構造。 C++ 11 7.1.6.3/2(7.1.5.3/2在C++ 98):詳細類型說明符中的類型依賴嵌套名稱說明符

3.4.4描述用於在的標識符名稱查找如何進行闡述型說明符 。如果標識符解析爲類名枚舉名,所述闡述型說明符將其引入聲明的相同的方式簡單型說明符引入其類型名

因此,雖然您可以形成一個合格的詳細說明類型說明符,但您需要注意它不會依賴於類型。在模板定義時間每3.4.4的名稱解析將永遠不會找到類名稱,因爲從屬名稱被假定爲對象,除非用前綴typename關鍵字(在此上下文中語法不允許)。

這是準確評估標準的含義和語言的設計意圖嗎?

+0

我不明白爲什麼它會是一個問題,如果它是類型依賴的,只要查找發生在實例化點。這是clang實現的,這就是爲什麼它允許'struct S1 :: I'然後診斷'struct S2 :: I'作爲http://ideone.com/paV3Kh中的錯誤(注意:ideone使用GCC,並且GCC允許這樣做,所以你沒有看到那裏的錯誤) – hvd

+0

@ hvd有趣,奇怪;謝謝!但真正想知道的是爲什麼'typename'關鍵字不是必需的。其實我還沒有查找那些不需要的例外列表,所以我現在就去做... – Potatoswatter

+0

好點。引用14。6p2:「假定模板聲明或定義中使用的名稱取決於* template-parameter *,則不會爲類型命名,除非可用的名稱查找找到類型名稱或名稱符合關鍵字'typename的 '「。我沒有看到允許'struct S1 :: I'的異常。 – hvd

回答

3

從註釋擴展:

拿這個程序爲例:

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 
} 

在模板定義時,既S2S3都還好:14.6p5列出在不需要typename例外。基本上:在使用是明確的,因爲名稱永遠不能是除類型以外的其他名稱,typename不是必需的。這包括typename在句法上不允許的幾種情況,所以在需要typename時意味着無法編寫程序。 typename struct S<T>::Istruct typename S<T>::I都是硬錯誤,並且struct S<T>::I是明確的。

在模板實例化時,的3.4.4規則是更清楚:既struct S1<int>::Istruct S2<int>::I然後可以發現,其中,很明顯,S2<int>::I是一個typedef,所以struct S2<int>::I是錯誤的。同時,在那個時候,S2<short>::I看起來不是typedef,而是一個結構,所以struct S2<short>::I被允許。

+0

謝謝!抱歉給你帶來不便;這個問題只是我記憶錯誤的結果,而且我之前會發佈一個答案,但我的互聯網連接已經結束:P – Potatoswatter

+0

@Patatoswatter我不知道這一點,所以就我自己的C++知識而言,這很好你問。 :) – hvd