Reputation: 64286
I want to store some additional information about classname during inheritance:
#define CLASS_TO_STRING(name) #name
class IBase {};
template <typename T>
struct BaseManager
{
static const char* MANAGER_TAG = CLASS_TO_STRING(T);
};
std::map<const char*, IBase*> mManagers;
template <typename T>
void addManager(BaseManager<T>* manager)
{
mManagers[T::MANAGER_TAG] = manager;
}
So, when I call addManager
with some object of type inherited from BaseManager
I get an error that BaseManager<TYPENAME>::MANAGER_TAG
is undefined. I understand the reason of the problem but can't understand how to resolve it.
Upvotes: 0
Views: 58
Reputation: 49986
You can change const char*
to constexpr
but I am afraid all you will get from CLASS_TO_STRING(T)
is T
(at least g++ gives me T on output - and thats because preprocessor runs before compilation and template instantiation).
also instead of T::MANAGER_TAG
, you should BaseManager<T>::MANAGER_TAG
. And your BaseManager should inherit from IBase if :
mManagers[BaseManager<T>::MANAGER_TAG] = manager;
is supposed to work.
The reason you get your error is I suppose that in-class initialization of static data member, works only for const integral types.
Upvotes: 1
Reputation: 22744
Apart from marcin_j's comment about in-class initialization (which works only in C++11 and for nonintegral types it requires constexpr), the real problem is this:
static const char* MANAGER_TAG = CLASS_TO_STRING(T);
When this line gets parsed by the preprocessor, CLASS_TO_STRING will turn T into the string literal "T". What's really going on here is that the preprocessor (the one performing macro substitution) has absolutely no idea of the template system and that T is a template parameter. You need a different approach here.
Upvotes: 2