C++中模板类中的静态字段初始化

Seb*_*ski 5 c++ static templates static-members

我正在尝试用C++创建一些自注册类.所以我尝试了类似于此处提供的解决方案.在这样做时,我偶然发现了一些奇怪的事情.

这是代码:

#include <iostream>

class StaticClassType {
public:
  StaticClassType() {
    // Notify when the static member is created
    std::cout << "We're in." << std::endl;
  }
};


template<typename T>
class TestClass1 {
public:
  TestClass1() { &m; }
private:
  // Static member in a template class
  static StaticClassType m;
};

template<typename T>
StaticClassType TestClass1<T>::m;


class TestClass2 : public TestClass1<TestClass2> {
public:
  TestClass2() { } // required; why?
};


int main() {
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

此代码TestClass1::m在启动时创建静态成员变量(从而在控制台上打印"We are in.") - 即在main()启动之前.但是,只有在我编写(空)构造函数TestClass2(如示例中所示)时,代码才有效.

为什么我需要编写这个构造函数?为什么编译器生成的默认构造函数没有做同样的事情?

此问题仅发生在模板类中.如果TestClass1不是模板类,代码将在不编写空构造函数的情况下工作TestClass2.

BЈо*_*вић 2

我创建了更小的示例(没有构造函数,这是不需要的):

#include <iostream>

class StaticClassType {
public:
  StaticClassType(int v) {
    // Notify when the static member is created
    std::cout << "We're in."<<v << std::endl;
  }
};


template<typename T>
class TestClass1 {
protected:
  // Static member in a template class
  static StaticClassType m;
};

template<typename T>
StaticClassType TestClass1<T>::m = StaticClassType(3);


class TestClass2 : public TestClass1<TestClass2> {
public:
    void foo()
    {
        (void)m;
    }
};

int main() {
  std::cout << "main" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

请注意,需要 foo() 方法,否则编译器将删除静态变量,因为它没有在任何地方使用。