2017-03-07 14 views
1

テンプレートを使用してベクトルを(数学的意味で)実装しようとしています。クラスに標準ベクトル定数を定義したいと思います。私は単純な定数(すべてゼロ、すべてのもの)でそれを行うことができましたが、より困難な単位ベクトル(与えられたインデックスに1つのコンポーネントを設定する以外はすべてゼロ)を定義するのに苦労しています。C++のテンプレートテンプレートクラスのstatic constメンバ変数

私はそれを行うためのエレガントな方法をまだ見つけられませんでした。

#include <iostream> 

template<unsigned int tSize, typename tReal> 
class Vector { 
public: 

    template<unsigned int tIndex> 
    static const Vector msUnit; 

    inline Vector() {} 

    template<typename...tTypes> 
    inline Vector (tTypes...pVals) { 
     set(mReals, pVals...); 
    } 

    inline tReal operator[] (unsigned int pIndex) { 
     return mReals[pIndex]; 
    } 

    inline const tReal operator[] (unsigned int pIndex) const { 
     return mReals[pIndex]; 
    } 

protected: 

    template<typename tType> 
    void set (tReal* pPtr, const tType pVal) { 
     *pPtr = pVal; 
    } 

    template<typename tType, typename...tTypes> 
    void set (tReal* pPtr, const tType pVal, const tTypes...pVals) { 
     *pPtr = pVal; 
     set(pPtr+1, pVals...); 
    } 

    tReal mReals [tSize]; 

}; 

int main() { 

    Vector<3,double> lVec = Vector<3,double>::msUnit<2>; 

    std::cout << "Vector: (" << lVec[0] << ", " << lVec[1] << ", " << lVec[2] << ")" << std::endl; 

    return 0; 
} 

をしかし、私はmsUnit静的なconstメンバテンプレートを定義する方法を発見していない:ここで私はそれを定義したい方法です。

私はこれを試してみました:

template<unsigned int tIndex, unsigned int tSize, typename tReal> 
    const Vector<tSize,tReal> Vector<tSize,tReal>::msUnit<tIndex>; 

しかし、コンパイラ(clang & gccは)文句を言う:ここでは

prog.cc:43:48: error: nested name specifier 'Vector<tSize, tReal>::' for declaration does not refer into a class, class template or class template partial specialization 
const Vector<tSize,tReal> Vector<tSize,tReal>::msUnit<tIndex>; 
          ~~~~~~~~~~~~~~~~~~~~~^ 
prog.cc:43:54: error: expected ';' at end of declaration 
const Vector<tSize,tReal> Vector<tSize,tReal>::msUnit<tIndex>; 
                ^
                ; 
prog.cc:43:54: error: expected unqualified-id 

は、このテストの実際の例です:http://melpon.org/wandbox/permlink/AzbuATU1lbjXkksX

はに、それも可能です静的constテンプレート変数メンバをテンプレートクラスに持っていますか?そしてもしそうなら、どのように?

さらに、msUnitテンプレートの初期設定を行う方法を見つける必要があります。

+1

私は、可変テンプレートと経験を持っていない(したがって、これはコメントではなく答えです)が、私は構文は 'テンプレート<符号なしであることを期待したいです Vector :: msUnit ; – Angew

+0

初期化子に関しては、おそらく再帰を伴います。 – Angew

+1

あなたの提案された定義は実際には何も定義しません。実際にテンプレートを定義するには、実際のテンプレートパラメータ、つまり 'tIndex'、' tSize'、 'tReal'を提供する必要があります。 –

答えて

3

あなたはすでにあなたのmsUnitをdecleareすることができますどのように方法を見つけた - あなたは2つのテンプレートを使用する必要があり、すなわち

template<unsigned tSize, typename tReal> 
template<unsigned tIndex> 
const Vector<tSize, tReal> Vector<tSize, tReal>::msUnit; 

あなたが現在1にn番目の引数を初期化するための一致するコンストラクタと他のすべてを持っていないので(私は推測することができません)ゼロには、あなたは自分の関数を使用することができます。あなたはすでにあなたのクラスの静的メンバにアクセスするとして、あなたはちょうどあなたがすでにそれを持っていますが、あなたが与えられたいくつかの他の機能を使用してベクトルを初期化し、すべてを

template<unsigned int tSize, typename tReal> 
class Vector { 
public: 
    // ... 

    template<unsigned int tIndex> 
    static const Vector msUnit; 

private: 
    static const Vector<tSize, tReal> createUnitVector(unsigned tIndex) { 
     Vector<tSize, tReal> v{}; 
     v.mReals[tIndex] = tReal(1); 
     return v; 
    } 

    tReal mReals [tSize]; 
}; 

template<unsigned tSize, typename tReal> 
template<unsigned tIndex> 
const Vector<tSize, tReal> Vector<tSize, tReal>::msUnit{Vector::createUnitVector(tIndex)}; 

を使用することができますので、あなたも、あなたの完全なクラスへのアクセス権を持っていますあなたのクラスで。

ここでは、ライブデモのために行く:http://melpon.org/wandbox/permlink/5b7cgXTeqXZDoCRp

+0

こんにちは、私は答えを受け入れたが、私はテンプレート静的メソッドに切り替えることを選択したので、テンプレート変数のためにC++ 14拡張を引き出す必要はありません。 – Lagf

関連する問題