带有模板的静态变量

Static variable with templates

本文关键字:静态 变量      更新时间:2023-10-16

我想在继承期间存储一些关于类名的其他信息:

#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;
}

因此,当我使用从BaseManager继承的某些类型对象调用addManager时,我收到一个错误,指出BaseManager<TYPENAME>::MANAGER_TAG未定义。我了解问题的原因,但不知道如何解决。

除了 marcin_j 关于类内初始化的评论(它仅适用于 C++11 并且对于非整数类型,它需要 constexpr),真正的问题是:

static const char* MANAGER_TAG = CLASS_TO_STRING(T);

当预处理器解析此行时,CLASS_TO_STRING会将 T 转换为字符串文字"T"。这里真正发生的事情是预处理器(执行宏替换的那个)完全不知道模板系统,并且 T 是一个模板参数。这里需要一种不同的方法。

你可以

const char*更改为constexpr但恐怕你从CLASS_TO_STRING(T)得到的只是T(至少 g++ 在输出上给了我 T - 那是因为预处理器在编译和模板实例化之前运行)。

也不要T::MANAGER_TAG,你应该BaseManager<T>::MANAGER_TAG。并且您的基本经理应该从IBase继承,如果:

mManagers[BaseManager<T>::MANAGER_TAG] = manager;

应该工作。

您收到错误的原因是我认为静态数据成员的类内初始化仅适用于 const 整型。