我想在继承期间存储一些关于classname的其他信息:
#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;
}
因此,当我使用从addManager
继承的某个类型的对象调用BaseManager
时,我得到一个BaseManager<TYPENAME>::MANAGER_TAG
未定义的错误。我理解问题的原因但无法理解如何解决它。
答案 0 :(得分:2)
除了marcin_j关于类内初始化的评论(仅适用于C ++ 11和非整数类型,它需要constexpr),真正的问题是:
static const char* MANAGER_TAG = CLASS_TO_STRING(T);
当预处理器解析此行时,CLASS_TO_STRING会将T转换为字符串文字“T”。这里真正发生的是预处理器(执行宏替换的那个)完全不知道模板系统,T是模板参数。你需要一个不同的方法。
答案 1 :(得分:1)
您可以将const char*
更改为constexpr
,但我担心您从CLASS_TO_STRING(T)
获得的所有内容都是T
(至少g ++会在输出时给出T - 这就是因为预编译器在编译和模板实例化之前运行。)
也代替T::MANAGER_TAG
,您应该BaseManager<T>::MANAGER_TAG
。如果出现以下情况,您的BaseManager应继承IBase:
mManagers[BaseManager<T>::MANAGER_TAG] = manager;
应该有用。
您收到错误的原因是我认为静态数据成员的类内初始化仅适用于const整数类型。