【问题标题】:Ensuring a static member of a class is constructed确保构造类的静态成员
【发布时间】:2013-11-13 21:19:34
【问题描述】:

考虑下面的代码

#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&amp; p = MyClass::p 这样的额外语句?

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

【问题讨论】:

  • [temp.inst]/10 “实现不应隐式实例化函数模板、[...] 或不需要实例化的类模板的静态数据成员。”并且从类模板特化派生不需要实例化(定义)其静态数据成员。
  • @DyP 为什么这不是答案?
  • @AlexanderB 因为它很短而且我很懒? :P
  • 我通过将 auto& p 更改为 Printer p 来实现它,但我想这不是你想要的:P

标签: c++ c++11 static


【解决方案1】:

适当的引用是 [temp.inst]/2

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

强调我的。


还有 [temp.inst]/1

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

和 [temp.inst]/10

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多