2017-03-07 141 views
1

我正在嘗試使用模板實現一個向量(在數學意義上)。我想在類中定義標準矢量常量。我設法做到了簡單常量(全零,全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靜態常量成員模板。

我嘗試這樣做:

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

它甚至有可能到模板類中有靜態常量模板變量成員?如果是的話如何?

而且我仍然需要找到一種方法來爲msUnit模板提供初始值設定項。

+1

我沒有與可變模板(因此這是一個評論,而不是答案)的經驗,但是我希望的語法是'模板<無符號int tSize,typename tReal> template const Vector Vector :: msUnit ;' – Angew

+0

對於初始化程序,它可能涉及遞歸。 – Angew

+1

你提出的定義並沒有真正定義任何東西。要真正定義一個模板,你必須提供實際的模板參數,即什麼是'tIndex','tSize'和'tReal'。 –

回答

3

你已經找到了如何decleare你msUnit的方式 - 你必須使用兩個模板,即

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

正如你目前沒有匹配的構造函數初始化第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