模板静态成员初始化顺序
Template static members initialization order
我有一个问题,有关以前的问题张贴在这里静态字段初始化顺序假设我有以下结构体,有两个静态成员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
的类型仍然未知,那么它们何时真正初始化?在main()
的模板实例化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
)。
相关文章:
- lambda 作为接受其他参数的参数的初始化顺序
- 大括号或等于初始值设定项初始化顺序
- 类内初始化与构造函数初始化列表的顺序
- C++ 模板中的静态常量初始化顺序
- 如果在 C++ 构造函数中以错误的顺序初始化对象数据,会发生什么类型的错误
- 视觉C++:在 DLL 加载期间,全局变量初始化顺序是否具有确定性?
- 构造函数中没有参数的对象类成员按什么顺序初始化?
- 销毁 pthread 互斥体和 C++ 中的取消初始化顺序
- 线程局部变量的初始化顺序
- 初始化值是否保证通过其自己的地址反映,而不考虑内存顺序
- 类静态变量初始化顺序
- 具有静态存储持续时间的常量初始化变量的初始化顺序
- 解析 CRTP 初始化顺序
- 初始化相等C++的顺序
- 内联初始化的静态 const 类成员的初始化顺序保证
- 使用constexpr的全局初始化顺序
- 初始化与类类型相同的静态成员(静态初始化顺序问题)
- 结构化绑定的标识符是否按顺序初始化?
- c++中的求值顺序初始化数组
- c++标准和C语言在哪里说的是一样的:编译单元(.cpp文件)中的变量是按照声明的顺序初始化的