2016-04-12 90 views
1

我需要將(幾個)類的實例關聯到小整數,我將其稱爲句柄模板超類的靜態成員定義

我討厭這樣做使用預處理宏,所以我想我會使用模板和多重繼承。

我定義了一個Handle類是這樣的:

#include <map> 

template<typename Key, typename Self> 
class Handle 
{ 
protected: 
    static Key nextHandle; 
    static std::map<Key, Self*> handles; 
    Key handle; 
public: 
    Handle() 
    { 
     handles[nextHandle++] = this; 
    } 

    virtual ~Handle() 
    { 
     handles.erase(handle); 
    } 

    static Self * byHandle(Key handle) 
    { 
     typename std::map<Key, Self*>::const_iterator it = handles.find(handle); 
     if(it == handles.end()) 
      return nullptr; 
     else 
      return it->second; 
    } 

    Key getHandle() 
    { 
     return handle; 
    } 
}; 

這種「模式」的用法是:

class Test : public SomeSuperclass, ... , public Handle<int, Test> 
{ 
public: 
    Test(); 
}; 

Test::Test() 
    : Handle() 
{ 
} 

int Handle<int, Test>::nextHandle = 666; 
std::map<int, Test*> Handle<int, Test*>::handles; 

的問題是在這裏^^^我不知道如何爲這些靜態變量定義存儲,我得到這個錯誤從鐺++:

handle_test.cpp:17:24: error: template specialization requires 'template<>'

int Handle::nextHandle = 666;

或,如果我嘗試做在測試類定義,如:

int Test::nextHandle = 666; 
std::map<int, Test*> Test::handles; 

我得到這個其他錯誤:如果你想模板專業化的靜態成員定義

handle_test.cpp:20:11: error: no member named 'nextHandle' in 'Test'

int Test::nextHandle = 666;

回答

2

,你可以:

template<> 
int Handle<int, Test>::nextHandle = 666; 
template<> 
std::map<int, Test*> Handle<int, Test>::handles; 

如果您想要主模板的靜態成員定義,您可以:

template<typename Key, typename Self> 
Key Handle<Key, Self>::nextHandle; 
template<typename Key, typename Self> 
std::map<Key, Self*> Handle<Key, Self>::handles; 

您無法在派生類Test上定義它們,它們是Handle的成員。

+0

首先提出的解決方案的作品,但第二個看起來更好! – fferri

+0

@mescalinum這取決於你想要什麼。如果你在代碼中都給出了這兩個參數,那麼在正常情況下,將使用主版本。 '處理','處理'等等。對於特殊情況,將使用專業化版本,即用於'處理'。如果你不需要特殊情況,那麼僅僅給出主版本就足夠了。 – songyuanyao