2017-10-04 108 views
4

我在另一個類模板中有一個類模板。內部類有一個靜態數據成員。我正在努力爲它提供一個定義。下面的例子作品在鐺3.8,但不是在GCC-7.1在模板類中定義模板類的靜態數據成員

template <typename T> 
struct Out { 
    template <typename U> 
    struct In { 
    static int var; 
    }; 
}; 

template <typename T> 
template <typename U> 
int Out<T>::template In<U>::var; 

GCC給出了錯誤:

error: template definition of non-template ‘int Out<T>::In<U>::var’ 
int Out<T>::template In<U>::var; 
          ^~~ 

什麼是我必須做的,使GCC幸福嗎?


編輯:原來擺脫template,使這項工作:

template <typename T> 
template <typename U> 
int Out<T>::In<U>::var; 

仍然留下一個問題,是template允許在這裏?

+0

不僅允許,而且還需要。此時,編譯器不知道是否Out :: In是一個typename /成員/模板。它會猜測成員,並猜測你想要在 ::,這是一個錯誤。較新的gccs,如上所述,在這裏提供有用的診斷;之前,情況更糟。 – lorro

+1

@lorro我認爲這是必要的,你給的理由。我的困惑得到了證實 –

回答

0

In之前沒有template這種類型的定義將更常見。此處不需要template關鍵字,因爲Out<T>::In是「當前專業化的成員」。

有關規定成員名稱前需要使用template關鍵字的規則,請參見[temp.names]/4。關於技術術語「當前專業化成員」的定義,請參見[temp.dep.type]/4。

但是關鍵字實際上是允許的,因爲語法允許它在任何::和名稱之間,並且語義只要求下面的名稱要麼與模板參數一起使用,要麼命名類模板([temp.names ]/5),並且標準中沒有其他規則禁止它。並且[temp.names]/5中的說明解釋:

[ Note: As is the case with the typename prefix, the template prefix is allowed in cases where it is not strictly necessary; i.e., when the nested-name-specifier or the expression on the left of the -> or . is not dependent on a template parameter, or the use does not appear in the scope of a template. - end note]

+0

當我省略'template'作爲'Out'的靜態數據成員時,我仍然感到困惑 –

+0

允許多餘'template'消歧器被允許改變的規則C++ 11。具體而言,「使用的部分不出現在模板範圍內」。 – Oktalist

相關問題