2012-09-07 84 views
2

在我面临的问题中,我需要一些或多或少像多态类一样的东西,但是它允许虚拟模板方法。如何用模板方法(C++)模拟类中的多态性?

重点是,我想创建一个子问题数组,每一个都是通过一个不同的类实现的不同技术来解决的,但是保存相同的接口,然后传递一组参数(这些参数是函数/函子 - 这是模板跳转的地方)到所有子问题并找回解决方案。

如果参数是,例如,整数,这将是这样的:

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; 
} 

但问题是,我需要的参数是这样的

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

,因此解决方法是喜欢的东西

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

哪些显然不能显示为虚拟的(所以不能从指针到基类)被称为...

现在我很卡,不知道怎么PROCEDE ...

+0

为什么不使用类模板而不是函数模板? – ForEveR

+0

我希望子问题hyerarchy建立一次,并能够得到不同的参数... – Davide

回答

1

通常,这种类型的问题是通过一个公用函数模板和一个受保护的虚函数来处理类型擦除对象来解决的。为了您的具体问题,这可以转化成这样:

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); 
    }; 
}; 

然后,你也可以专门为不同类型的参数存储对象的param_list模板。对于仿函数,你可以做同样的事情。这当然是有限的,但通常可以在大多数情况下工作。否则,您仍然可以依靠类似的保护与公共职能模式。例如,你可以在公共接口中拥有一组非模板虚函数,它们都只是调用一个私有函数模板(对于所有情况都是一个实现),但这并不美观,但是如果可能的模板数论据是有限的。

+0

谢谢...需要研究一点,现在我的大脑的KO,但它似乎是我一直在寻找 – Davide

0

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

+0

你的意思是类似'模板类Arg:公共ArgBase {...}'和ArgBase持有接口? 听起来不错... – Davide

+0

是的,这就是主意。 –