Reputation: 18950
I need to associate the instances of (several) class(es) to small integers, which I call handles.
I'd hate doing this using preprocessor macros, so I thought I'd use templates and multiple inheritance.
I defined a Handle
class like this:
#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;
}
};
and the usage of this "pattern" would be:
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;
the problem is here ^^^ I don't know how to define the storage for those static variables, I get this error from clang++:
handle_test.cpp:17:24: error: template specialization requires 'template<>'
int Handle::nextHandle = 666;
or, if I try do define it in the Test class, such as:
int Test::nextHandle = 666;
std::map<int, Test*> Test::handles;
I get this other error:
handle_test.cpp:20:11: error: no member named 'nextHandle' in 'Test'
int Test::nextHandle = 666;
Upvotes: 1
Views: 51
Reputation: 173014
If you want static member definition of template specialization, you could:
template<>
int Handle<int, Test>::nextHandle = 666;
template<>
std::map<int, Test*> Handle<int, Test>::handles;
If you want static member definition of primary template, you could:
template<typename Key, typename Self>
Key Handle<Key, Self>::nextHandle;
template<typename Key, typename Self>
std::map<Key, Self*> Handle<Key, Self>::handles;
You couldn't define them on derived class Test
, they're members of Handle
.
Upvotes: 2