2012-10-11 40 views
1

我有這個類因式分解的N維向量空間的常用操作:繼承的賦值賦值操作,如何返回正確的類型?

template <unsigned int N> 
struct BaseVector 
{ 
    float m_data[N]; 
    // Common operations like dot product, magnitude, test for unity, etc. 
}; 

注:我真的想因式分解儘可能多的代碼,以儘量減少文檔和測試的量。

現在,我導出兩個類:

// 3D geometric vectors 
struct Vector3 : public BaseVector<3> 
{ 
    Vector3 Cross(const Vector3& other); 
    // ... 
}; 

// Quaternions are a particular kind of vector space 
struct Quaternion : public BaseVector<4> 
{ 
    void Interpolate(const Quaternion& start, const Quaternion& end, ...); 
    // ... 
}; 

這些類表現類似加法和標量乘法(逐個分量操作);所以,我想分解operator+=()operator*=()在基向量類中。

我的問題是:如何返回適當類型的引用?到目前爲止(在下面進行說明)

template <unsigned int N> 
struct BaseVector 
{ 
    ??? & operator+=(const BaseVector& other) 
    { 
     transform(m_data, m_data+N, other.m_data, m_data, plus<float>()); 
     return ??? 
    } 
}; 

我所有的想法都不能讓人滿意,我希望得到一些建議,謝謝!


想法#1:使用C++協變返回類型機制。但是,我必須在派生類中重載這些運算符 - 我是對的嗎? (這意味着重複測試給我。)

想法#2:去模板?

template <unsigned int N> 
struct BaseVector 
{ 
    template <typename T2> 
    T2 & operator+=(const T2& other) 
    { 
     transform(...); 
     return *this; // THIS IS WRONG! I'm trying to "upcast" 
    } 
}; 

理念#3:比化代碼到基本載體的私有成員,但後來我不得不在派生類中添加更多的功能(和更多的東西來測試)

template <unsigned int N> 
struct BaseVector 
{ 
private: 
    void DoOperatorPlus(const BaseVector& other) { transform(...); } 
}; 

struct Vector4 : public BaseVector<4> 
{ 
    Vector4& operator+=(const Vector4& other) 
    { 
     DoOperatorPlus(other); 
     return *this; 
    } 
}; 

回答

3

出來你真的嘗試使用CRTP

的想法是,你給一個模板參數的基類派生類中:

template <unsigned int N, typename Derived> 
    struct BaseVector 
    { 
     Derived & operator+=(const Derived& other) 
     { 
      transform(m_data, m_data+N, other.m_data, m_data, plus<float>()); 
      return static_cast<Derived&>(*this); 
     } 
    }; 

我並不是100%確定收益聲明,但這應該會給你一個想法。

+1

我在MSVC中的'return'語句上得到了一個編譯時轉換錯誤,但是把它改成'return static_cast (* this);'似乎可以解決它。 – user1201210