2013-06-26 43 views
0

由於我不想重新定義方法,我想使用泛型,因此我遇到了模板專門化的問題。如何避免在模板專業化中重新定義類方法?

template<class VarsContainer, class Specific> 
class State 
{ 
public: 
    State(); 
    ~State(){} 

    HSError_t Update(LoggerData const &lData); 
    VarsContainer state; 

    void swap(State &rhs); 
    State & operator=(State rhs); // pass by value copy 

protected: 
    void UpdateSpecific(Specific *rhs); 
    Specific specificPtr; 
}; 

並在實施我做到以下幾點:

template<class VarsContainer, class Specific> 
HSError_t State<VarsContainer, Specific>::Update(LoggerData const &lData) 
{ 
    HSError_t error_t = HeatInterfaceError; 
    specificPtr = const_cast<Specific>(&lData); 
    error_t = UpdateSpecific(specificPtr); 
    if(error_t != HeatSuccess) 
    { 
    return error_t; 
    } 
    return error_t; 
} 

template<class VarsContainer, class Specific> 
HSError_t State<VarsContainer, Specific>::UpdateSpecific(Specific *rhs) 
{ 
    HSError_t error_t = HeatInterfaceError; 
    return error_t; 
} 

這樣做,我專注於以下方式模板後:

template<> 
class State<ChemicalVars, Chemicals*> 
{ 
public: 
    ChemicalVars state; 

protected: 
    HSError_t UpdateSpecific(Chemicals *chemicals); 
    Chemicals *specificPtr; 
}; 

而且我在一個CPP文件中定義UpdateSpecific將數據從專用結構複製到本地狀態。

問題是,當我嘗試調用「Update」方法時,編譯器沒有在我的ChemicalVars的專門模板中爲它創建一個定義。

後來,我改變我的專長有:

template<> 
class State<ChemicalVars, Chemicals*> 
{ 
public: 
    ChemicalVars state; 
    HSError_t Update(LoggerData const &lData); 

protected: 
    HSError_t UpdateSpecific(Chemicals *chemicals); 
    Chemicals *specificPtr; 
}; 

但儘管如此,錯誤是一樣的:

undefined reference to `State<ChemicalVars, Chemicals*>::Update(LoggerData const&)' 

問題是通用的實現是不錯的,我只是想用定義的在專業化使用的通用國家。

回答

1

專門化類模板意味着只要該類使用特定的專用類型實例化,它就會使用專用的定義。這就是你得到第一個未定義錯誤的原因。但是當你添加專門的更新函數但沒有定義它時,而是假定它使用默認的函數,那麼就會導致第二個錯誤消息,因爲它沒有按照你的意願使用默認函數,而是試圖尋找專門的更新定義。我認爲你想要的待辦事項是這樣一個更抽象的:

//This will hold all function common to template param for State class 
template<typename Container, typename Specific> 
struct CommonStateDefinition{ 
    void Update(StructData const &lData){ 
     std::cout<<"In CommonStateDefinition::Update" << endl; 
    } 
}; 

template<typename Container, typename Specific> 
struct State{ 
    CommonStateDefinition<Container,Specific> m_stateImpl; 
    void Update(StructData const &lData){ 
     std::cout << "In State::Update" << endl; 
     m_stateImpl.Update(lData); 
    } 
} 

template<> 
class State<ChemicalVars, Chemicals*>{ 
    CommonStateDefinition<ChemicalVars,Chemicals*> m_stateImpl; 
    //use the common update via delegation 
    void Update(StructData const &lData){ 
     std::cout << "In State<ChemicalVars,Chemicals*>::Update" << endl; 
     m_stateImpl.Update(lData); 
    } 
    //add other specialized function 
} 
3

專業化和基本模板的定義在某種程度上是不相關的。專業化繼承任何來自基礎模板的東西,你將不得不重新定義你需要的基礎模板中的所有功能。

常用的解決方法是將基本模板拆分爲一個基類,該基類具有所有專業化通用的所有代碼,然後從基本模板和專業化中的代碼繼承,以便可以重用通用代碼。

+0

似乎是一個很好的解決方法,非常感謝你大衛。將立即着手並在幾分鐘內發佈解決方案。 – Claudiordgz