简体   繁体   English

如何使用模板方法(C ++)模仿类中的多态性?

[英]How to mimic polymorphism in classes with template methods (c++)?

in the problem i am facing i need something which works more or less like a polymorphic class, but which would allow for virtual template methods. 在我面临的问题中,我需要某种或多或少类似于多态类的东西,但需要使用虚拟模板方法。

the point is, i would like to create an array of subproblems, each one being solved by a different technique implemented in a different class, but holding the same interface, then pass a set of parameters (which are functions/functors - this is where templates jump up) to all the subproblems and get back a solution. 关键是,我想创建一个子问题数组,每个子问题都可以通过在不同类中实现的不同技术来解决,但要保持相同的接口,然后传递一组参数(即函数/函子-在这里模板跳至所有子问题,然后返回解决方案。

if the parameters would be, eg, ints, this would be something like: 如果参数是例如ints,则将类似于:

struct subproblem
{
...
virtual void solve (double& solution, double parameter)=0; 
}
struct subproblem0: public subproblem
{
...
virtual void solve (double& solution, double parameter){...}; 
}
struct subproblem1: public subproblem
{
...
virtual void solve (double* solution, double parameter){...}; 
}

int main{
subproblem problem[2];
subproblem[0] = new subproblem0();
subproblem[1] = new subproblem1();
double argument0(0),
       argument1(1),
       sol0[2],
       sol1[2];
for(unsigned int i(0);i<2;++i)
    {
    problem[i]->solve( &(sol0[i]) , argument0);
    problem[i]->solve( &(sol1[i]) , argument1);
    }
return 0;
}

but the problem is, i need the arguments to be something like 但问题是,我需要将参数设置为类似

Arg<T1,T2> argument0(f1,f2)

and thus the solve method to be something of the likes of 因此,求解方法类似于

template<T1,T2> solve (double* solution, Arg<T1,T2> parameter)

which cant obviously be declared virtual ( so cant be called from a pointer to the base class)... 显然不能声明为虚拟的(因此不能从指向基类的指针调用)...

now i'm pretty stuck and don't know how to procede... 现在我很困,不知道如何进行...

Typically, this type of problem is solved with a public function template and a protected virtual function taking in a type-erasure object. 通常,这种类型的问题可以通过使用公共函数模板和带有类型擦除对象的受保护虚拟函数来解决。 For your specific problem, this could translate into this: 对于您的特定问题,可以将其转换为:

struct param_list_base {
  virtual double getParam(int i) const = 0;
};

template <typename ParamStorage>
struct param_list : param_list_base {
  const ParamStorage& params;
  param_list(const ParamStorage& aParams) : params(aParams) { };
  virtual double getParam(int i) const {
    return params[i];
  };
};

class subproblem {
  protected:
    virtual void solve_impl(double* sol, param_list_base* params) = 0;
  public:
    template <typename ParamStorage>
    void solve(double* sol, ParamStorage params) {
      param_list<ParamStorage> tmp(params);
      solve_impl(sol, &tmp);
    };
};

And then, you can also specialize the param_list template for different kinds of parameter storage objects. 然后,您还可以将param_list模板专用于不同类型的参数存储对象。 For functors, you can do the same. 对于函子,您可以执行相同操作。 This is, of course, somewhat limited, but it usually can be made to work in most cases. 当然,这在一定程度上受到限制,但是通常在大多数情况下都可以使它起作用。 Otherwise, you can still rely on a similar pattern of protected versus public functions. 否则,您仍然可以依靠受保护的功能与公共功能的相似模式。 For example, you can have a set of non-template virtual functions in the public interface, which all just call a private function template (one implementation for all the cases), this isn't pretty but it works if the number of possible template arguments is limited. 例如,您可以在公共接口中有一组非模板虚拟函数,它们全部都只是调用一个私有函数模板(在所有情况下都是一个实现),这虽然不漂亮,但如果可能的模板数量很多,它就可以工作参数是有限的。

声明一个抽象基类,并让您的模板继承于此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM