3

考虑以下代码

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

我希望这会打印出“已创建”,但是,它不会打印出任何内容(使用 MSVC 和 ideone gcc c++11 进行了测试)。这是编译器实现问题,还是标准支持这种行为?如果注释掉的行没有注释,那么它会按预期打印出来。有什么方法可以在static Printer p不需要更改 MyClass 或额外的语句(如auto& p = MyClass::p?

我对此感兴趣的原因是我希望创建一个模板化的基类,当它派生时它将在启动时运行一些代码。

4

1 回答 1

2

适当的报价是 [temp.inst]/2

除非类模板或成员模板的成员已被显式实例化或显式特化,否则当在需要成员定义存在的上下文中引用特化时,成员的特化将被隐式实例化;特别是,静态数据成员的初始化(以及任何相关的副作用)不会发生,除非该静态数据成员本身的使用方式要求该静态数据成员的定义存在。

强调我的。


还有 [temp.inst]/1

类模板特化的隐式实例化导致类成员函数、成员类、作用域成员枚举、静态数据成员和成员模板的声明的隐式实例化,而不是定义或默认参数的隐式实例化 [...]

和 [temp.inst]/10

实现不应隐式实例化函数模板、[...] 或不需要实例化的类模板的静态数据成员。

于 2013-11-13T21:30:59.943 回答