C ++ 03
そのように解決B
すること( injected -class-nameと呼ばれ、テンプレートのインスタンス化を含むすべてのクラスの暗黙的に宣言されたメンバー)は、便宜上の目的です。私はそれがそのようになるのを見たことがありません!
回避するには、名前::
の前に名前(および必要に応じて名前空間の名前)を追加して名前を修飾します。
template <typename T>
class B {
A< ::B> member; // whitespace required to prevent digraph; see comments
};
C ++ 11
C++11§14.6.1/1は指定します(私の強調)
通常の(非テンプレート)クラスと同様に、クラステンプレートには注入されたクラス名があります(第9節)。注入されたクラス名は、テンプレート名またはタイプ名として使用できます。template-argument-listとともに、template template-parameterのtemplate-argumentとして、またはfriendクラステンプレート宣言のelaborated-type-specifierの最終識別子として使用される場合、クラステンプレート自体を参照します。 。それ以外の場合は、<>で囲まれたクラステンプレートのtemplate-nameの後にtemplate-parametersが続くのと同じです。
したがって、この問題がC ++ 11で発生する場合は、コンパイラのバグです。上記の回避策。
注—比較のために、C++03の対応する段落は次のとおりです。
通常の(非テンプレート)クラスと同様に、クラステンプレートには注入されたクラス名があります(9節)。注入されたクラス名は、template-argument-listの有無にかかわらず使用できます。template-argument-listなしで使用する場合、注入されたclass-nameの後に<>で囲まれたクラステンプレートのtemplate-parametersが続くのと同じです。template-argument-listとともに使用する場合は、指定されたクラステンプレートの特殊化を参照します。これは、現在の特殊化または別の特殊化である可能性があります。
ご覧のとおり、テンプレート名に含まれるかどうかに応じて、識別子をクラスまたはテンプレートにすることができる特殊なケースがすでに1つあります。彼らはさらにいくつかのケースを追加しました。