6

数学ベクトル テンプレートを書きたいです。多くの数学演算メソッドを使用して、型とサイズをテンプレート引数として受け入れるクラスがあります。ここで、たとえば Vector<3> がそれぞれ data[0..3] を参照するメンバーとして x、y、z を持つ特殊化を作成したいと考えています。

問題は、基本クラスを作成したり、すべてを 2 回書いたりせずに、デフォルトのテンプレートからすべてを継承する特殊化を作成する方法がわからないことです。

これを行う最も効率的な方法は何ですか?

template<class Type, size_t Size>
class Vector {
    // stuff
};

template<class T>
class Vector<3,T>: public Vector {
    public:
        T &x, &y, &z;
        Vector(): Vector<>(), x(data[0]), y(data[1]), z(data[2]){}
        // and so on
};
4

2 に答える 2

7

どういうわけか、デフォルトの実装から派生できるはずですが、インスタンスを特殊化しています。そこから派生できる、特殊化されていないバージョンである必要があります。それは簡単です:

// Add one extra argument to keep non-specialized version!
template<class Type, size_t Size, bool Temp = true>
class Vector {
    // stuff
};
// And now our specialized version derive from non-specialized version!
template<class T>
class Vector<T, 3, true>: public Vector<T, 3, false> {
    public:
        T &x, &y, &z;
        Vector(): Vector<>(), x(data[0]), y(data[1]), z(data[2]){}
        // and so on
};
于 2012-10-16T21:51:15.583 に答える
1

これを少し異なる方法で作成することを検討してください。ただし、目標は達成されます。外部インターフェイスを追加します。スタンドアロン関数 X()、Y()、Z() を意味します。

template<class T, size_t S>
T& x(Vector<T, S>& obj, typename std::enable_if<(S>=1)>::type* = nullptr)
{
   return obj.data[0];
}

template<class T, size_t S>
T& y(Vector<T, S>& obj, typename std::enable_if<(S>=2)>::type* = nullptr)
{
   return obj.data[1];
}

template<class T, size_t S>
T& z(Vector<T, S>& obj, typename std::enable_if<(S>=3)>::type* = nullptr)
{
   return obj.data[2];
}

以下の間に大きな違いはありません。

 Vector<T, 3>& obj
 return obj.x();

 Vector<T, 3>& obj
 return x(obj);

おまけとして、このインターフェイスはサイズを一致させるために機能します。

于 2012-10-16T21:53:47.133 に答える