C++ 模板中的静态常量初始化顺序
C++ Static const initialization order in templates
冒着被标记为重复的风险,我抓住机会。 请考虑以下事项:
给定以下静态常量数组 arrA 和 arrB,arrB 取决于 arrA。
#include <iostream>
#include <string>
#include <array>
template<int N>
class MyClass {
public:
static const std::array< int, N> arrA;
static const std::array< int, N> arrB;
};
template<int N>
std::array<int, N> const MyClass<N>::arrA = []() -> decltype(auto) {
std::array<int, N> arr;
for (int i = 0; i < N; i++) {
arr[i] = 1 + i;
}
return arr;
} ();
template<int N>
std::array<int, N> const MyClass<N>::arrB = []() -> decltype(auto) {
std::array<int, N> arr;
for (int i = 0; i < N; i++) {
arr[i] = arrA[i] + 1;
}
return arr;
} ();
int main()
{
constexpr int i = 3;
std::cout << std::to_string(MyClass<i>::arrB[0]) << std::endl;
}
如果我理解正确,这是标准中给出的静态常量成员无序初始化的情况:
1( 无序动态初始化,仅适用于(静态/线程本地(类模板静态数据成员和未显式专用化的变量模板(自 C++14 起(。对于所有其他动态初始化,此类静态变量的初始化是不确定的,除非程序在初始化变量之前启动线程,在这种情况下,其初始化是未排序的(自 C++17 起(。此类线程局部变量的初始化相对于所有其他动态初始化是无序的。
我能找到的最佳答案就在这里,但没有提到是否有一种已知的模式允许以有序的方式执行这种初始化。在保持static const
的同时,这甚至可能吗?
理想情况下,我希望数组保持const
,否则问题就微不足道了。
虽然这个例子可以用constexpr
构建,但在实际情况下需要动态初始化(我使用<random>
(。
编辑:我发现有趣的是,无论源代码中声明或定义的顺序如何,arrB
都会在arrA
之前初始化。
如果要保证初始化的顺序,则必须将两个数组包装在一个结构中,并使用结构的构造函数来初始化静态变量。这是我的意思的一个例子。
#include <iostream>
template <typename T>
struct A {
struct B {
B() : c(0), d(c + 1) {}
T c;
T d;
};
static B b;
static T& c() {
return b.c;
}
static T& d() {
return b.d;
}
};
template <typename T>
typename A<T>::B A<T>::b{};
int main() {
std::cout << A<int>::b.c << ", " << A<int>::b.d << std::endl;
std::cout << A<int>::c() << ", " << A<int>::d() << std::endl;
return 0;
}
如果你这样做,你可能想要提供访问器,如示例(c()
和d()
( - 你也可以使用结构是私有的,并且对访问器的结果具有恒定性,所以,例如,你可以做
template <typename T>
struct A {
static const T& c() {
return b.c;
}
static T& d() {
return b.d;
}
private:
struct B {
B() : c(0), d(c + 1) {}
T c;
T d;
};
static B b;
};
相关文章:
- 当一个值是非常量但用常量表达式初始化时使用constexpr
- 如何使用数据对象上的常量指针初始化类
- 为什么C++常量模板化向量在使用之前没有初始化?
- 犰狳C++ - 从常量内存初始化只读矩阵而不复制
- 从另一个静态常量数组初始化静态常量数组(只需少量计算)
- C++ 模板中的静态常量初始化顺序
- 具有静态存储持续时间的常量初始化变量的初始化顺序
- 当 T 具有非平凡析构函数时,类类型 T 的对象是否可以常量初始化?
- 对常量初始化的困惑
- 在不同翻译单元中具有静态存储持续时间的依赖非局部常量浮点变量的常量初始化
- 使用静态常量初始化unique_ptr时出现未定义的引用错误
- 正在从常量初始化字符数组
- 如果首先使用非常量初始化,为什么允许对 const 的非常量引用?
- 通过元编程自动+静态类内常量初始化
- 多个数据成员的常量初始化
- 使用整数常量0初始化实例,但不使用其他常数值或整数变量
- float的类内静态常量初始化与C++中的int有何不同
- 用常量初始化数组无效
- 在常量初始化器中调用constexpr构造函数的限制
- Java风格的静态常量初始化