2013-02-14 53 views
0

假設我有以下代碼:不同的行爲 - 模板的模板參數

template <template <typename> class T> 
class A {}; 

template <typename T> 
class B 
{ 
    A<B> instance; 
}; 

int main() 
{ 
    B<int> instance; 
} 

GCC 4.7.2和GCC 4.8.0編譯此代碼確定,而ICC 13.0.1和鐺3.2給了我一個錯誤(clang需要:: B而不是B,而icc在模板實例中也需要<之後的空格)。

誰是對的?

我找到了關於它的線程(Template class that refers to itself as a template template parameter?),但我無法理解該標準的14.6.1/2並且還看到了LLVM錯誤14350(http://www.mail-archive.com/[email protected]/msg21095.html)。那麼,鏗鏘和英特爾在這裏錯了嗎?

回答

1

14.6.1說:

注入的類名可以作爲一個模板類型名稱。當它被用來與模板參數列表,作爲模板參數爲模板模板參數,或如在最終標識符闡述型說明符朋友類模板聲明的它指的是類模板本身。

「注入類名」是類注入到該類的範圍內的類模板的名稱(B)。換句話說,它指在類別B的定義內使用非限定名稱B。如果您在需要模板名稱的上下文中使用該名稱:即使用顯式模板參數(B<int>)或作爲模板的模板參數(採用模板模板參數(A<B>)),它應該引用模板本身。

所以,gcc是正確的。

此外,在C++ 11中,<::B>中的<之後不需要空格。根據2.5節,第3段,將所述輸入流中的令牌時:

如果下一三個字符是<::和隨後的字符既不是:也不>,所述<通過本身視爲預處理器令牌和而不是作爲替代標記<:的第一個字符。 (<:是另一種書寫方式[。)

+0

我可以在這種情況下同時使用:: B和B兩種形式嗎? – FrozenHeart 2013-02-14 20:15:50

+0

@NikitaTrophimov,當你想引用模板時,你可以使用':: B'。 – rici 2013-02-14 20:33:06