2014-05-18 95 views
3

我正在將一段代碼從一個幾何庫轉換爲另一個幾何庫。在我現在的代碼中,我有很多專門的Point類,我寧願有一個單獨的模板。新的模板化的,有一個重載的加法運算符,定義爲;如何讓子類中的運算符返回子類類型?

T是所包含的類型,N是點的尺寸元數。

爲了提供舊的使用界面,我不得不繼承Point類。主要是通過混淆一些成員,並增加一些功能;

// Old library, could be indexed by var.x, ... 
// New library, can only be indexed via. var[i] 
int& x = data[0]; 
int& y = data[1]; 
int& z = data[2]; 

// Old library, supplied this function, new one didn't. 
void subclass_function(); 

這個工程就像一個魅力,這個替代品在整個程序中的大部分調用站點都是它的工作。也就是說,除非有一個運算,然後通過兼容性類提供的功能,說:

IntPoint3 index; 
// The scalar multiplication results in the Point<int, 3>. 
(index * 2).subclass_function(); 

錯誤:Point<int, 3>沒有subclass_function()定義。

這是什麼建議的解決方案? - (即獲得運營商返回子類型)

注1:我寧願編輯Point類,包裝比算術運算符重載所有,在各專業子類。

注2:專用子類不添加狀態。

+0

我對這個問題的標題感到困惑。你的問題與'operator =='有什麼關係? –

+0

不幸的是,您必須重新定義派生類中的所有運算符才能執行此操作。 –

+0

@VaughnCato他意味着他有'Base :: operator +'返回'Base',他希望表達式'derived_a + derived_b'返回一個'Derived'。 –

回答

1

使用奇怪重複的模板模式(CRTP)。

基部templatePoint_impl採取它的派生類型作爲參數。

它從操作員返回派生類型。

template<class T, unsigned N, class D> 
struct Point_impl { 
    D* self() { return static_cast<D*>(this); } 
    D const* self() const { return static_cast<D const*>(this); } 

    template<typename U, typename D2> 
    D operator+(Point_impl<U,N,D2> const& o) const { 
    auto retval = *self(); 
    retval += o; 
    return retval; 
    } 
}; 

然後派生:

struct Bob:Point_impl<int,3,Bob>{ 
    //... 
}; 

我發現static_assertselfis_base_of明智的爲好,因爲它抓住了一些錯別字。

+0

猜猜你還在使用手機,或者今天是「節省空間吧一天」? ;)(你有一個流浪的''') – dyp

+0

@dyp製作燒烤,是的。不要使用任何自動更正,因爲它比編寫錯誤的代碼更糟糕! – Yakk