2016-05-30 75 views
2

假設我有一個基類是這樣的:奇怪的遺傳模式

class Abstract { 
    public: 
    /* This type should be the deriver of this class */ 
    virtual DerivedType foo(void) = 0; 
}; 

我想DerivedType取決於誰從這個類派生有所不同。事實上,我想DerivedType是從AbstractDerives類型。

我意識到,我可以做這樣的事情:

template<typename der_t> 
class Abstract { 
    public: 
    virtual der_t foo(void) = 0; 
}; 

然後它應該像這樣使用:

class Derived : public virtual Abstract<Derived> { }; 

不幸的是沒有辦法強迫某人在正確的傳遞鍵入模板。這就是有人能做到這一點:

class Derived : public virtual Abstract<int> { }; 

那麼,有沒有更好的方式來做到這一點,還是有辦法迫使某人在正確的參數傳遞?

+4

你想得到的是類似於[CRTP](https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)。我沒有太多的經驗,但似乎通常假設用戶將把正確的模板參數。 – user463035818

+0

爲什麼它不幸*模板的用戶可以通過一個「錯誤」(我寧願說不同)類型?我發現它使模式更加通用和靈活。儘管需要不同類型的情況可能很少見。 – user2079303

+1

我認爲你可以使用靜態斷言來檢查關係,但是在添加強制執行特定用法的代碼之前,我會考慮可能發生的最糟糕的事情,並且如果可能發生的事情甚至可能是有用的。 – molbdnilo

回答

2

慣用的伎倆了CRTP的是有一個私人的構造函數只有傳入的類可以通過friend指令訪問:

template <class Derived> 
struct Crtp { 

private: 
    friend Derived; 

    Crtp() = default; 
}; 

它不是完美的,但對錯誤警衛。

注:static_assert ING是不是一個實用的解決方案,因爲當時Crtp實例化Derived仍然是不完整的,並且不能被檢查的基類。

+0

'朋友派生;' - 很棒的技巧,不知道你可以朋友模板參數。 – Rotem