Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When do constructors of static members of template classes get called in C++?

There is plenty of information on when constructors of static members of ordinary classes are called. However, I am seeing some strange behavior with regard to template classes.

What should the output of the following program be? (Note I use printf to avoid any static initialization order fiasco complications with std::cout.)

#include <iostream>

class B {
public:
  B(const std::string &s) { printf("Hello I am B from %s\n", s.c_str()); }
};

template<typename T>
class Atempl {
public:
  static B b_;
};

class A {
public:
  static B b_;
};

template<typename T>
B Atempl<T>::b_("Atempl");
B A::b_("A");

class C : public Atempl<int> {
};

int main(int argc, const char *argv[]) {
  return 0;
}

I think the output should be:

Hello I am B from A
Hello I am B from Atempl

But with g++ 4.3 on FreeBSD 7.3 I get:

Hello I am B from A

If I add the line

template class Atempl<int>;

all is well and I get the expected output. The question is, why doesn't the declaration of class C count as an instantiation of the template Atempl and cause B's constructor to be called? Is this part of the standard or a bug in g++ 4.3?

like image 301
Manish Avatar asked Aug 05 '11 16:08

Manish


People also ask

When and how obtain a static constructor called?

A static constructor is called automatically. It initializes the class before the first instance is created or any static members declared in that class (not its base classes) are referenced. A static constructor runs before an instance constructor.

How do static members of a class get initialized?

We can put static members (Functions or Variables) in C++ classes. For the static variables, we have to initialize them after defining the class. To initialize we have to use the class name then scope resolution operator (::), then the variable name. Now we can assign some value.

How many times static constructor gets executed in a class?

Times of Execution: A static constructor will always execute once in the entire life cycle of a class. But a non-static constructor can execute zero time if no instance of the class is created and n times if the n instances are created.

Can we have constructors for static classes?

Static classes cannot contain an instance constructor. However, they can contain a static constructor. Non-static classes should also define a static constructor if the class contains static members that require non-trivial initialization.


2 Answers

In a class template, when performing implicit instantiation, the members are instantiated on demand. Since the code does not use the static member, it is not even instantiated in the whole application.

When you do an explicit intantiation, the whole class and all of its members are instantiated, and that includes the static member variable, which is then initialized and you get your expected result.

Without the explicit instantiation you could do something like B* p = &Atempl<int>::b_; (or any other use of the static member) to trigger the instantiation.

like image 176
David Rodríguez - dribeas Avatar answered Nov 01 '22 23:11

David Rodríguez - dribeas


When a static member of a class template template is initialized is unspecified. In fact, unless you actuall use the static member, it should not be instantiated, and so never be initialized. If you explicitly instantiate the template, you force the instantiation of all of the members, which in turn forces the initialization (but I think exactly when it will be initialized is still unspecified).

like image 36
James Kanze Avatar answered Nov 02 '22 00:11

James Kanze