Template static members initialization order

一笑奈何 提交于 2019-12-02 03:06:52

问题


I have a question related to a previous question posted here Static field initialization order Suppose I have the following struct, with 2 static members x and y (templated types themselves)

#include <iostream>

using namespace std;

template <typename T>
struct Foo
{
    static T x;
    static T y;
    Foo()
    { 
         cout << "x = " << x << endl;
         cout << "y = " << y << endl;
    }
};

template <typename T>
T Foo<T>::x = 1.1f;

template <typename T>
T Foo<T>::y = 2.0 * Foo<T>::x;


int main()
{
    Foo<double> foo;
}

Output:

x = 1.1 
y = 2.2

I initialize x and y above main(), and you can see that y depends on x, so it better be that x is initialized first.

My questions:

  1. At the point of initialization, the types of x and y are still unknown, so when are they really initialized? Are the static members actually initialized after the template instantiation Foo<double> foo; in main()?
  2. And if yes, the order of declarations of x and y seems not to matter, i.e. I can first declare y then x (both in the struct and in the static initialization) and still get the correct output, i.e. the compiler knows somehow that y is dependent on x. Is this a well defined behaviour (i.e. standard-compliant)? I use g++ 4.8 and clang++ on OS X.

Thanks!


回答1:


This code is safe because Foo<double>::x has constant initialization, but Foo<double>::y has dynamic initialization.

3.6.2/2:

Constant initialization is performed:

  • ...

  • if an object with static or thread storage duration is not initialized by a constructor call and if every full-expression that appears in its initializer is a constant expression.

Together, zero-initialization and constant initialization are called static initialization; all other initialization is dynamic initialization. Static initialization shall be performed before any dynamic initialization takes place.

On the other hand, if you had:

double tmp = 1.1;

template <typename T>
T Foo<T>::x = tmp;

template <typename T>
T Foo<T>::y = 2.0 * Foo<T>::x;

that code would not be "safe" - Foo<double>::y could end up being either 2.2 or 0.0 (assuming nothing else modifies tmp during dynamic initializations).



来源:https://stackoverflow.com/questions/23841022/template-static-members-initialization-order

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!