模板静态成员初始化顺序 [英] Template static members initialization order
问题描述
我有一个与此处张贴的问题相关的问题静态字段初始化顺序
假设我有下面的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
首先进行初始化。
我的问题:
- 在初始化阶段, code> x 和
y
仍然未知,所以什么时候它们真的被初始化?是静态成员实际上初始化模板实例化Foo< double> foo;
- 如果是,则
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:
- At the point of initialization, the types of
x
andy
are still unknown, so when are they really initialized? Are the static members actually initialized after the template instantiationFoo<double> foo;
inmain()
? - And if yes, the order of declarations of
x
andy
seems not to matter, i.e. I can first declarey
thenx
(both in the struct and in the static initialization) and still get the correct output, i.e. the compiler knows somehow thaty
is dependent onx
. 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屋!