冒着被标记为重复的风险,我捕获了机会。 请考虑以下事项:
给定以下静态常量数组 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) Unordered dynamic initialization, which applies only to (static/thread-local) class template static data members and variable templates (since C++14) that aren't explicitly specialized. Initialization of such static variables is indeterminately sequenced with respect to all other dynamic initialization except if the program starts a thread before a variable is initialized, in which case its initialization is unsequenced (since C++17). Initialization of such thread-local variables is unsequenced with respect to all other dynamic initialization.
我能找到的最佳答案是 here但没有提及是否存在允许以有序方式执行此类初始化的已知模式。在保持 static const
的同时是否有可能?
理想情况下,我希望数组保持 const
, 否则问题是微不足道的。
虽然这个例子可以用 constexpr
构建,在实际情况下需要动态初始化(我使用 <random>
)。
编辑:我觉得有趣的是,无论源代码中声明或定义的顺序如何,arrB
在 arrA
之前初始化.
最佳答案
如果你想保证初始化的顺序,你必须将两个数组包装在一个结构中,并使用结构的构造函数来初始化静态变量。 Here是我的意思的一个例子。
#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()
) - 你也可以使用结构访问器的结果是私有(private)的和常量的,所以,例如,你可以这样做
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;
};
关于模板中的 C++ 静态常量初始化顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61887372/