1

ええ、テンプレートの仮想クラス メンバー関数を使用することはできません。その部分を理解しようとするのではなく、それは理にかなっています...そして、私は悪魔のように多重/仮想継承を回避しようとしています。

テンプレート クラス A と、A から継承する抽象テンプレート クラス B、および B から継承する C があります。

template <typename T>
class A 
{
protected:
   T val; 
public:
   A(T a) {val = a;}
   T val() {return val();}

   template <typename J>
   A<J> cast_as() { return A<J>((J)val); }
};

template <typename T>
class B : public A<T>
{
protected:
  int b;
public:
   B(T a) : A(a){b=10*a;}
   virtual foo() = 0;
   //and I'd like, but this can't exist
   //template <typename J>
   //B<J>* BCastAs();

};

template <typename T>
class C : public B<T>
{
protected:
  int c;
public:
  C(T c) : B(c) { c=c+1;}
  virtual foo() override { cout << (a+b+c);}
};

int main() { C<int> c(10); B<double>* b = c.BCastAs<double>();}

そして、私はそれを行う方法を考えることはできません... B * は実際にそれが C であることを実際に知る必要がないため (クローン呼び出しの戻りと同じように)、それは可能であるように感じますが、私はしません仮想テンプレート メンバー関数を使用せずに c を正しく移動させる方法がわかりませんが、これは不可能です。

4

1 に答える 1

1

あなたが投稿したサンプル コードは、一見すると重大な設計上の欠陥があるように見えます。

通常、クラス テンプレートに仮想関数を含める必要はありません。これは、CRT パターンを使用して仮想関数を回避できるためです。

定義されたインターフェイスを実装する継承されたクラスを必要とするという意図を作ります(これは、テンプレートを「抽象化」する方法です)。インターフェイスは、純粋な仮想メソッドとして定義されている場合と定義されていない場合があります (できれば、静的インターフェイス チェックも同様に定義され、メソッドの実装が欠落している場合に発生する不思議なコンパイラ エラー メッセージが少なくなります)。

このようなテンプレート フレームワークのサンプルと、この手法の使用方法は、私のSTTCL テンプレート ライブラリで確認できます。

要するに:静的ポリモーフィズムを使用してください。

更新:
はい、私も STTCL で純粋仮想メソッドを使用していますが、まったく異なる方法で使用しています (継承階層の完全なセットを結合するための基本的なエントリ ポイントとして)。

于 2013-07-02T22:48:27.197 に答える