2011-06-03 45 views
15

This snippet(取自this question)用g ++編譯得很好(如圖所示),只要返回類型之前的template就在那裏。相比之下,VC10不會編譯代碼,出現以下錯誤:哪個編譯器是正確的?模板返回類型之前需要'模板'嗎?

error C2244: 'A::getAttr' : unable to match function definition to an existing declaration

如果我刪除了template,VC10是幸福的,但G ++慘叫此錯誤:再次因爲VC的破碎

error: non-template 'AttributeType' used as template
note: use 'A::template AttributeType' to indicate that it is a template

是它兩階段查找或原因是什麼?哪個編譯器就在這裏?我懷疑g ++是正確的,因爲我在這裏需要template的模糊內存,就像分配器內部的rebind模板一樣。


編輯:我們有一個贏家:G ++/GCC(驚喜驚喜...)。


template <typename T, typename K> 
class A { 
public: 
    T t; 
    K k; 

    template <int i, int unused = 0> 
    struct AttributeType{ 
    }; 

    template <int i> 
    AttributeType<i> getAttr(); 

}; 

template <typename T, typename K> 
template <int i> 
typename A<T, K>::template AttributeType<i> A<T, K>::getAttr() { 
//    ^^^^^^^^ -- needed or not? 
    return t; 
} 


int main(){ 
    A<int,int> a; 
} 
+3

郵政問題的代碼。堆棧溢出支持並強烈鼓勵這一點。 – 2011-06-03 20:29:07

+1

一般來說,標準合規的非正式「參考編譯器」是Comeau,您可以嘗試提交您的代碼片段(http://www.comeaucomputing.com/tryitout/)來查看其判斷。 - 編輯:現在嘗試,該片段編譯它很好,因爲它是在Ideone。 – 2011-06-03 20:29:30

+0

@Merlyn:想要保持這個問題簡短,儘管如此。 – Xeo 2011-06-03 20:31:08

回答

10

GCC是正確的。 AttributeType是一個依賴的模板名稱,後面跟着尖括號<,因此在這裏需要使用關鍵字template來消除模糊性,這使得編譯器清楚接下來是模板名稱。該規則在§14.2/ 4提到:

When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6.2), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template.

@Johannes已經寫在這裏很好的解釋:

Where and why do I have to put the "template" and "typename" keywords?

+2

謝謝,那是我正在尋找的標準報價。 – Xeo 2011-06-03 21:02:35