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

2023-12-20

目前我正在开发一个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> with T="要导出的类"。例子:

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

where 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 ...类模板特化的隐式实例化导致声明的隐式实例化, 但不是类成员的定义或默认参数 函数、成员类、作用域成员枚举、静态 数据成员和成员模板;它会导致隐含的 无作用域成员枚举定义的实例化和 匿名工会成员。

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

14.7.1p8 类模板的隐式实例化不会导致该类的任何静态数据成员被隐式实例化。

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

         ExportToLua() { (void)&m_registered; }

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

模板类的静态成员变量的隐式初始化 的相关文章

随机推荐