2017-10-04 7 views
4

私は別のクラステンプレートの中にクラステンプレートを持っています。内部クラスには静的データメンバーがあります。私はそれを定義するのに苦労しています。私はgccを幸せにするために何を得たかテンプレート化されたクラス内でテンプレート化されたクラスの静的データメンバーを定義する

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

:以下の例は、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で打ち鳴らす3.8で動作しますが、いないはエラーになりますか?


編集:結局のところ、この仕事にするtemplateを取り払う:、まだ疑問が残り

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

templateここで許可されていますか?

+0

許可されていますが、必要です。この時点で、Out :: Inがtypename/member/templateであるかどうかは、コンパイラは認識しません。それはメンバーを推測し、あなたが ::を望んでいると推測します。これはエラーです。上記のように、より新しいgccは、ここで有用な診断を提供します。以前はずっと悪かったです。 – lorro

+1

@lorro私はそれがあなたが与えた理由のために必要だと思った。私の混乱は –

答えて

0

定義のこのタイプは、より一般的にIntemplateずに見られます。 Out<T>::Inは「現在の専門分野のメンバー」であるため、templateというキーワードはここでは必要ありません。 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'の静的データメンバとして 'In'を扱わないでしょう理由について困惑して確認された –

+0

冗長' template'ディスアンビギュエータが許可されている場所についてのルールが変更しましたC++ 11。具体的には、「使用はテンプレートのスコープには表示されません」。 – Oktalist

関連する問題