3

次の方法で、実行時にテンプレート パラメーターを使用してクラスをインスタンス化することは可能ですか?:

#include <iostream>
#include <vector>

using namespace std;

template<typename T>
struct Foo {
  vector<T> d;
};

template<typename T>
struct Solver {
  Foo<T> data;

  virtual void calc() = 0;
};

struct SolverA : Solver<int>
{
  void calc() 
  {
    cout << "PRINT A\n";
  }
};

struct SolverB : Solver<double>
{
  void calc() 
  {
    cout << "PRINT B\n";
  }
};

int main()
{
  ... solver;

  if (...) {
    solver = new SolverA;
  } else {
    solver = new SolverB;
  }

  solver->calc();
}

したがって、クラスSolverASolverBにはテンプレート パラメーターはありませんが、コンパイル時にどれを使用するかを決定することはできません。私はこれに使用しようとしましたが、関数を呼び出すboost::any変数よりもキャストする方法がわかりませんでした。他のアイデアはありますか?solvercalc()

4

2 に答える 2

3

クラスのインターフェースを追加します。

#include <iostream>
#include <vector>

using namespace std;

template<typename T>
struct Foo {
  vector<T> d;
};

struct SolverIface
{
  virtual void calc() = 0;
};

template<typename T>
struct Solver : SolverIface {
  Foo<T> data;
};

struct SolverA : Solver<int>
{
  void calc()
  {
    cout << "PRINT A\n";
  }
};

struct SolverB : Solver<double>
{
  void calc()
  {
    cout << "PRINT B\n";
  }
};

int main()
{
  SolverIface *solver;

  if (0) {
    solver = new SolverA;
  } else {
    solver = new SolverB;
  }

  solver->calc();
}

テンプレートと仮想ディスパッチはうまくいきません。

于 2012-10-19T10:15:05.900 に答える
2

SolverASolverB完全に無関係なタイプであるため、存在しない、または存在する必要があります。それらは異なる基本クラスを持っています。

あなたができることは次のとおりです。

struct SolverInterface
{
  virtual void calc() = 0;
};

template<typename T>
struct Solver : SolverInterface {
  Foo<T> data;
};


int main()
{
   SolverInterface* solver;
   if (...) {
      solver = new SolverA;
   } else {
      solver = new SolverB;
   }
   solver->calc();
}
于 2012-10-19T10:14:53.060 に答える