4

clang ++(clang 3.2を試しました)は、テンプレートクラスの名前を、クラススコープ内で発生するテンプレートではなく、インスタンス化されたクラスとして扱うようです。たとえば、次のコード

template <template <class> class T>
class A {};

template <typename T>
class B {
    A<B> member;
   // ^---- clang++ treats B as an instantiated class
         // but I want it to be a template here
         // this code could compile in g++
};

int main()
{
    B<int> b;
    return 0;
}

それをコンパイルするにはどうすればよいですか?

4

2 に答える 2

3

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つあります。彼らはさらにいくつかのケースを追加しました。

于 2013-01-12T08:05:24.837 に答える
1

これは、C ++ 11の時点では不適合な動作です。これは、挿入されたクラス名(クラス本体内で自動的に宣言される名前)がテンプレートテンプレートパラメーターに渡されるときにテンプレートであるとC++11が言うためです。したがって、コードはC++03実装でのみ失敗するはずです。

ただし、これに関するバグレポートを今すぐ開く必要はありません。私はすでにそれをずっと前にやりました。

于 2013-01-12T12:00:24.043 に答える