c++ - 模板类静态成员变量的隐式初始化

标签 c++ templates inheritance static-members

目前我正在开发一个 C++ 项目,我计划在其中嵌入 Lua 脚本。出于这个原因,某些类需要导出到 Lua,我想让这更方便,因此我创建了一个模板类:

template <class T>
class ExportToLua {
    public:
        ExportToLua() {}
        ~ExportToLua() {}
    private:
        static int m_registered;
};
template <class T> int ExportToLua<T>::m_registered = T::exportToLua();

现在每个需要导出的类都派生自ExportToLua<T>T ="要导出的类"。示例:

 class Example: public ExportToLua<Example> {
 public:
     Example();
     virtual ~Example();
     static int exportToLua();
 private:
 };

哪里Example的静态成员函数 exportToLua()持有类特定的注册码。我的理解是静态成员变量ExportToLua<T>::m_registered的实例每个编译单元都存在 - 即 - 每个 T .

但是当我启动我的程序时,注册码永远不会被调用。例如在 example.cpp 中:

 int Example::exportToLua() {
     std::cout << "int Example::exportToLua()" << std::endl;
     return -2;
 }

但是当我运行我的程序时我从来没有看到这条消息。

知道为什么吗?编译器是否“优化”了静态变量 m_registered ,因为我没有在任何地方使用它?

感谢您的参与,

最好的, 克里斯托夫

最佳答案

如果编译器隐式实例化一个包含静态成员的类模板,则这些静态成员不会被隐式实例化。只有当编译器需要静态成员的定义时,编译器才会实例化静态成员。

这种行为得到了 C++ 标准的支持,这里是段落

14.7.1p1 ... The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions or default arguments, of the class member functions, member classes, scoped member enumerations, static dataembers and member templates; and it causes the implicit instantiation of the definitions of unscoped member enumerations and member anonymous unions.

和@gx_ 找到的另一个相关部分

14.7.1p8 The implicit instantiation of a class template does not cause any static data members of that class to be implicitly instantiated.

解决方法是@gx_ 提到的:只需添加

         ExportToLua() { (void)&m_registered; }

给构造函数。获取地址会强制实例化静态变量 m_registered。

关于c++ - 模板类静态成员变量的隐式初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18570632/

相关文章:

c++ - 如何使用 typeid 来计算指针中数据的类型?

c++ - 具体功能作为默认模板参数

c++ - 使用模板继承调用祖 parent 构造函数

c# - 用抽象类型实现抽象类

java - 子类化和泛型

c++ - 模板中的默认参数

c++ - 为什么要有指针参数?

c++ - 如何一次创建多个线程

inheritance - 可继承的对象结构

c++ - 调整二维 vector 的大小 - 错误