【发布时间】:2013-09-02 10:09:45
【问题描述】:
目前我正在开发一个 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 进行了一些“优化”,因为我没有在任何地方使用它?
感谢您的意见,
最好, 克里斯托夫
【问题讨论】:
-
也许你必须在
class Example的编译单元(源文件)中显式实例化基础,即template class ExportToLua<Example>;。 -
在这里回答:stackoverflow.com/a/17132624/688659。活生生的例子:ideone.com/4kTHYg (vs ideone.com/N5wJNE)
-
@gx_ 这个答案远不能令人满意。它指的是一个特定的编译器,并不说明代码的合法性/正确性。
-
14.7.1p1 ... 类模板特化的隐式实例化会导致类成员函数、成员类、作用域成员的声明的隐式实例化,但不会导致定义或默认参数的隐式实例化枚举、静态数据成员和成员模板;它会导致无范围成员枚举和成员匿名联合的定义的隐式实例化。
-
感谢标准报价! @Walter 你在这里=)(我现在可以将此权威参考添加到我对另一个问题的回答中)。我认为您可以发布自己问题的答案。
标签: c++ templates inheritance static-members