2015-01-21 65 views
1

我目前無法像我想的那樣設置我的班級成員。我的模板類只專門用於合理的整數類型(無符號和「小」)。每個專業都需要一個相當大的查找表,而這個表只取決於類型。所以我認爲它一定是靜態的(和const)並且只創建一次。熱在初始化專用模板代碼中的靜態const成員?

由於C++沒有靜態構造函數,我知道您可以創建一個類,它在初始化時執行繁重的操作,並將其作爲靜態成員。

我我的代碼減少到這些基礎:

// Of this, I only want one instance per type, 
// because the table can get big. 
template<class T> 
struct LookUp 
{ 
    static int const SIZE = 1 << (sizeof(T) << 3); 
    std::vector<T> table; 

    LookUp() 
     : table{ SIZE } 
    { 
     for (int i = 0; i < SIZE; ++i) 
     { 
      // Dummy code 
      table[i] = i; 
     } 
    } 
}; 

// "Normal" template class with common code for all types. 
template<class T> 
class LbpHelper 
{ 
    typedef /*...*/ image; 
}; 

// No functionality for the general case. 
template<class T> 
class Lbp 
{ 
}; 

// But for this (among others) we have something. 
template<> 
class Lbp<uint8_t> : public LbpHelper<uint8_t> 
{ 
    typedef uint8_t value_type; 
    typedef Lbp::image image; 

    static LookUp<value_type> _lookup; // <-- This is the mean one. 

public: 

    // Stuff... 
}; 

初始化靜態成員似乎混淆了很多用戶,尤其是當它涉及到的模板和專業化。我在這裏閱讀了很多答案,但沒有一個能解決我的問題。

我試圖具有類似

// The type of the class is the same as the type of the member class. 
template<> LookUp<uint8_t> Lbp<uint8_t>::_lookup{}; 
template<> LookUp<uint16_t> Lbp<uint16_t>::_lookup{}; 

文件或兩者。我嘗試了在頂括號中使用或不使用class T(並且當然使用T),而將template<>全部省略,僅在源文件中有{} - 我不知道還有什麼。沒有工作。

的Visual C++或者告訴我,_lookup不是成員或它不是可以專門或該實體:錯誤C2373:「_lookup」:重新定義;不同類型的修飾符

有人可以告訴我該放哪裏以便編譯?

回答

1

剛落template<>位,並把靜態數據成員的定義在.cpp文件:

LookUp<uint8_t> Lbp<uint8_t>::_lookup{}; 
LookUp<uint16_t> Lbp<uint16_t>::_lookup{}; 

[Live example]

...和,因爲_lookup的類型是類,你也可以省略{};它的默認構造函數將被調用。如果你使用不支持統一初始化的版本,這可能會請VC++。

爲什麼這是正確的方法:template<>用於引入明確的專業化。你是而不是引入了明確的專業化 - 你正在定義一個的數據成員已經定義了明確的專業化。

這是通過C++ 11覆蓋14.7.3/5:

...顯式專門類模板的成員中相同的方式定義爲正常類的成員 ,和不使用語法爲template<>。當定義明確專用的成員類的成員時,同樣的 是正確的。 ...

+0

令人驚訝的是,我100%確定我試過這個,但它沒有幫助。看來我必須在準備這篇文章時清除了另一個錯誤。正如他們總是說的那樣,「僅僅向其他人解釋問題可能已經帶來了新的見解。」 – primfaktor 2015-01-21 11:28:48