1

N次元ベクトル空間での一般的な演算を因数分解するために、このクラスがあります。

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

注:ドキュメントとテストの量を最小限に抑えるために、できるだけ多くのコードを分解したいと思っています。

ここで、2つのクラスを導出します。

// 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;
    }
};
4

1 に答える 1

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);
        }
    };

returnステートメントについて100%確信があるわけではありませんが、これでアイデアが得られるはずです。

于 2012-10-11T07:54:20.080 に答える