0

次のようなテンプレートがあります。

template<typename T>
struct foo {
  foo(T t) {
    //code
  }
  virtual double computation() = 0;
  //other members
};

ユーザーに独自のサブクラスにカスタムを提供してもらいT、次のcomputation()ようにします。

struct my_foo : public foo<std::string> {
  double computation() override { return 9.99; }
};

問題は、これが機能しないことです:

my_foo("hello");

スーパークラスのコンストラクターを呼び出すだけの場合でも、サブクラスごとに新しいコンストラクターを作成するようにユーザーに依頼する必要があります。これはばかげているように見えます。

私により適した代替の「デザインパターン」を提案できますか?

4

2 に答える 2

1

あなたの例からわかる限り、ユーザーは型と計算関数を指定する必要があります。仮想デストラクタを提供しなかったため、結果のテンプレートのインスタンス化を多態的に使用したくないと思います。たとえば、同じ場所に異なる実装を保存/交換したくないと思いますfoo<string>。言い換えれば、純粋仮想関数の唯一の目的はcomputation()、クライアントによる実装を必須にするようです。

さらに、クライアントがテンプレートを再実装したり、クラスに明示的にインポートしたりすることなく、テンプレートのコンストラクターを使用できるようにする必要があります。これは、 が派生クラスではなく、my_fooのインスタンスである場合にのみ実現できます。foo

その場合、ポリシー ベースの設計を使用できます。

template<typename T, typename ComputationPolicy>
struct foo : ComputationPolicy {
  foo(T t) {
    //code
  }

  void bar() {
    double d = ComputationPolicy::computation(); //just use it!
  }

  //...
};

テンプレートのユーザーは、 double に変換可能な値を返す function を持つ型を定義する必要がありcomputation()ます。そうしないと、テンプレートをインスタンス化できません。

struct myComp  {
  double computation() { return 9.99; }
};

typedef foo<std::string, myComp> my_foo;

my_foo("hello");
于 2013-06-18T06:21:21.530 に答える