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