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它,但我不确定如何转换变量solver来调用函数calc()。还有其他想法吗?

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 回答