带模板的静态变量

时间:2014-02-16 16:29:11

标签: c++ oop templates

我想在继承期间存储一些关于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未定义的错误。我理解问题的原因但无法理解如何解决它。

2 个答案:

答案 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整数类型。