2010-06-25 68 views
6

我將我的C++ windows代碼(msvc & intel)移植到Linux(g ++)。代碼使用了很多模板(我喜歡元編程;-)。但是我不能編譯這個代碼:g ++模板問題

template <class TA> 
struct A 
{ 
    template <class TAB> struct B; 
}; 


template <class TC> 
struct C {}; 


template <class TD> 
struct D 
{ 
    template <class TTD> class T {}; 
}; 


template<class TA> 
    template<class TBA> 
struct A<TA>::B : C<typename D<TA>::T<TBA> > 
{ 
    int foo; 
}; 

g ++告訴我,在A :: B的定義中,C類具有無效的模板參數。但在msvc和intel上它效果很好!這裏有什麼問題? PS:抱歉,我無法發佈原始代碼,因爲它太模板複雜。但是這個例子幾乎是一樣的,並且在g ++上給出了相同的錯誤。 謝謝。

更新:我發現問題是T的TBA參數g ++ doensn't像使用第二個模板的定義。

+0

我見過編譯「模板模板結構......」語法之前,但我從來沒有知道它的含義或爲什麼它是合法的語法。這是什麼意思(當像這樣的結構前面提到兩次「模板」)? – Dennis 2010-06-25 19:51:18

+1

@ Dennis:它需要在封閉模板之外定義嵌套模板,請參閱[這裏](http://www.comeaucomputing.com/techtalk/templates/#outsidedef)。 – 2010-06-25 19:53:35

+0

TA是A的模板參數,TAB是A的模板參數:: B – f0b0s 2010-06-25 19:56:29

回答

10

您需要template關鍵字

template<class TA> 
    template<class TBA> 
struct A<TA>::B : C<typename D<TA>::template T<TBA> > 
{ 
    int foo; 
}; 

GCC是正確的給診斷這裏。這是因爲T無法在從屬範圍D<TA>中查找。 <的含義取決於T是否爲模板。該標準說T應被假定爲不是模板,因此T不能跟隨模板參數列表。

template就像它告訴編譯器把T爲模板typename,而且<在任何情況下的參數列表的開始。標準說,在對模板參數進行明確限定段落14.2/214.2/4

對於模板的名稱,該名稱必須已知是指 爲模板。

當成員模板專門名稱出現後。或 - 在後綴表達式中,或者在限定id中的嵌套名稱說明符之後,並且postfix-expression或qualified-id顯式依賴於模板參數(14.6.2),則成員模板名稱必須是由關鍵字模板作爲前綴。否則,該名稱被假定爲命名一個非模板。

在你的情況,你有嵌套的名稱說明符D<TA>這取決於模板參數TAT出現。爲了正確解析類型名稱說明符,構造D<TA>::T<TBA>必須將T解釋爲類模板的名稱,14.2禁止該類名稱。


在那個話題,它總是一個好主意,試圖與Clang

main1.cpp:21:37: error: use 'template' keyword to treat 'T' as a dependent template name 
struct A<TA>::B : C<typename D<TA>::T<TBA> > 
            ^
            template 
1 error generated. 
+1

BRILLIANT,THANX! – f0b0s 2010-06-25 19:53:20

+0

好吧,我明白了。我大談第二'typename'關鍵字,但現在是'模板'。 – f0b0s 2010-06-25 20:05:03

+0

哇,我真的很喜歡這個診斷信息,現在這就是你期望的理想編譯器。 – 2010-06-26 12:34:54