简体   繁体   中英

Static field initialization in template class in C++

I'm trying to create some self-registering classes in C++. So I tried the solution similar to the one provided here . While doing this I stumble over something strange.

Here's the code:

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

This code create the static member variable TestClass1::m on startup (thereby printing "We're in." to the console) - ie before main() is started. However, the code only works if I write a (empty) constructor for TestClass2 (as shown in the example).

Why do I need to write this constructor? Why doesn't the default constructor generated by the compiler does the same thing?

This problem only occurs for template classes. If TestClass1 wasn't a template class, the code would work without writing the empty constructor for TestClass2 .

I created even smaller example (without constructors, which are not needed) :

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

take a note that foo() method is needed, otherwise the compiler removes the static variable, since it's not used anywhere.

From my point of view the "issue" is that in "Template world" the compiler will generate only what is really used by the client code. Here You never instanciate the TestClass2 class. Therefore a lot of code won't be generated. Try :

int main() {

  TestClass2 instance;
  return 0;
} 

And it works then.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM