模板静态成员初始化顺序 [英] Template static members initialization order

查看:206
本文介绍了模板静态成员初始化顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个与此处张贴的问题相关的问题静态字段初始化顺序
假设我有下面的struct,有两个静态成员 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

x y 上面 main()看到 y 取决于 x ,所以最好是 x 首先进行初始化。



我的问题:


  1. 在初始化阶段, code> x 和 y 仍然未知,所以什么时候它们真的被初始化?是静态成员实际上初始化模板实例化 Foo< double> foo;

  2. 如果是,则 x y 似乎没有关系,即我可以先声明 y 然后 x (在结构体和静态初始化中),仍然得到正确的输出,即编译器知道 y 依赖于 x 。这是一个明确定义的行为(即符合标准)吗?我在OS X上使用g ++ 4.8和clang ++。

谢谢!

解决方案

这段代码是安全的,因为 Foo< double> :: x 有常量初始化,但 Foo< double> :: y 有动态初始化。



3.6.2 / 2:


执行常规初始化




  • ...

    如果具有静态或线程存储持续时间的对象未由构造函数调用初始化,并且初始化器中出现的每个完整表达式都是常量表达式,则

  • < >


零初始化和常量初始化称为静态初始化;所有其他初始化是动态初始化


另一方面,如果你有:

  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 )。


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!

解决方案

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).

这篇关于模板静态成员初始化顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆