其他分享
首页 > 其他分享> > c-模板静态成员初始化顺序

c-模板静态成员初始化顺序

作者:互联网

我有一个与以前的问题有关的问题在这里Static field initialization order
假设我具有以下结构,带有2个静态成员x和y(模板类型本身)

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

输出:

x = 1.1 
y = 2.2

我在main()上方初始化x和y,您可以看到y取决于x,因此最好先初始化x.

我的问题:

>在初始化时,x和y的类型仍是未知的,那么它们何时真正初始化?静态成员是在模板实例化Foo< double>之后实际初始化的吗? FOO;在main()中?
>如果是,则x和y的声明顺序似乎无关紧要,即我可以先声明y,然后再声明x(在结构和静态初始化中都可以)并仍然获得正确的输出,即编译器以某种方式知道y取决于x.这是定义明确的行为(即符合标准的行为)吗?我在OS X上使用g 4.8和clang.

谢谢!

解决方法:

该代码是安全的,因为Foo< double> :: x具有常量初始化,而Foo< double> :: y具有动态初始化.

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.

另一方面,如果您有:

double tmp = 1.1;

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

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

该代码将不是“安全的”-Foo< double> :: y最终可能是2.2或0.0(假设在动态初始化期间没有其他修改tmp的功能).

标签:c,templates,static,static-members
来源: https://codeday.me/bug/20191011/1896151.html