考虑以下代码
#include <iostream>
using namespace std;
struct Printer{
Printer(){
std::cout << "Created\n";
}
};
template<class Derived>
struct InitPrinter{
static Printer p;
};
template<class Derived>
Printer InitPrinter<Derived>::p;
struct MyClass:InitPrinter<MyClass>{
MyClass(){}
};
// Uncomment line below to print out created
//auto& p = MyClass::p;
int main() {
return 0;
}
我希望这会打印出“Created”,但是,它不打印任何内容(使用MSVC和ideone gcc c ++ 11测试)。这是编译器实现问题,还是标准支持此行为?如果注释掉的行未取消注释,则按预期打印出来。有没有办法static Printer p
实例化而不需要更改MyClass或额外的语句,如auto& p = MyClass::p
?
我对此感兴趣的原因是我希望创建一个模板化的基类,它将在启动时运行一些代码。
答案 0 :(得分:2)
适当的引用是[temp.inst] / 2
除非已明确实例化或明确实例化类模板或成员模板的成员 special,在引用特化时隐式实例化成员的特化 在需要成员定义存在的上下文中; 特别是初始化(以及任何相关的 除非静态数据成员本身以某种方式使用,否则不会发生静态数据成员的副作用 这需要存在静态数据成员的定义。
强调我的。
还有[temp.inst] / 1
类模板特化的隐式实例化会导致隐式 类成员函数,成员类,作用域成员枚举,静态数据成员和成员模板的声明的实例化,但不是定义或默认参数的实例化[...]
和[temp.inst] / 10
实现不得隐式实例化不需要实例化的类模板的函数模板,[或]静态数据成员。