2016-04-12 16 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; 

問題は、私は方法がわからない^^^こちらこれらの静的変数の記憶域を定義するには、clang ++からこのエラーが発生します。

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

int Handle::nextHandle = 666;

または試してみるとあなたは、あなたがテンプレートの特殊化の静的メンバの定義が必要な場合

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

int Test::nextHandle = 666;

答えて

2

ができます:私は、この他のエラーが出る

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

:など、Testクラスで定義する

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

最初に提案された解決策が動作しますが、2番目の解決策はさらに優れています。 – fferri

+0

@mescalinumそれはあなたが何を望むかによって異なります。両方のコードをコードに渡すと、通常の場合、プライマリバージョンが使用されます(例: 'Handle '、 'Handle 'などのようになります。特別な場合には、特殊化バージョン、すなわち 'Handle 'のために使用されます。特別なケースが必要ない場合は、プライマリバージョンを与えるだけで十分です。 – songyuanyao