2012-09-07 121 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

是的,這就是主意。 –