1

私は次のことをします。

template <class C> class B{};

template <class X> 
struct  A{
  int member;
};

template <class Y> 
struct  A<B<Y>>{
    A(int n):member(n){}
};

int main(int, char**){}

つまり、クラス X はテンプレート自体である可能性があり、その場合、クラス A テンプレートの特殊化が必要です。
しかし、コンパイラは言う:

d:\>g++ -std=gnu++11 -o spec.exe spec.cpp
spec.cpp: In constructor 'A<B<Y> >::A(int)':
spec.cpp:11:14: error: class 'A<B<Y> >' does not have any field named 'member'  

クラスA<B<Y>>が から完全に分離されてAいる場合、すべてが正しく、 のメンバーが存在しない可能性がありますA。しかし、私はの専門化が欲しいA。すべてのコンテンツで。
または、Afor ケース when Xisの特殊なコンストラクターである可能性がありB<Y>ます。
実装方法は?

4

2 に答える 2

2

テンプレートの特殊化は、継承とはまったく異なるメカニズムです。一般的なテンプレートの内容を拡張するのではなく、特殊なケースの新しい内容に置き換えます。したがって、コンパイラは正しいです。クラスA<B<Y>>には という名前のフィールドがありませんmemberintといくつかの追加の自動生成関数 (コピー コンストラクター、デストラクターなど)を取るコンストラクターのみがあります。

テンプレートの内容を「継承」する場合は、次の 2 つのオプションがあります。

  • テンプレートからスペシャライゼーションにすべてをコピーします
  • 共通内容を基底クラスに入れて継承する

やりたいことに応じて、これらのオプションのいずれかが他のオプションよりも優れています。

于 2013-01-04T11:21:29.750 に答える
1

これを実装する方法は次のとおりです。

template <class C> class B{};

template <class X>
struct  A{
  int member;
};

template <class Y>
struct  A<B<Y> >{ // A<
    int member;  // just add member here
    A(int n):member(n){}
};

クラステンプレートの特殊化を実装すると、まったく新しいクラスを定義しているようなものになります。

あなたが探しているのはメンバー関数の特殊化だと思いますが、これは部分的な特殊化をサポートしていません。特定のテンプレートクラスのコンストラクターを特殊化しようとしている場合、このコンストラクターは暗黙的に宣言する必要があります。

template <class C> class B{};

template <class X>
struct  A{
  A(int n); // I implicitly-declared the constructor that I want to specialize. 
            // you can still define it if you want.
  int member;
};
// this is the contructor specialization,
// Note this isn't partial specialization, it's explicit specialization so you
// must provide a type that you want to specialize it with, in this case B<int>
template <>
A<B<int> >::A(int n):member(n){}
于 2013-01-04T11:41:34.987 に答える