冒着被标记为重复的风险,我抓住了机会。考虑以下内容:
给出以下静态常量数组arrA和arrB,取决于arrA的arrB。
#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;
}
如果我理解正确,这是标准中给出的静态const成员无序初始化的情况:
1)无序动态初始化,仅适用于未明确专门化的(静态/线程本地)类模板静态数据成员和变量模板(自C ++ 14起)。相对于所有其他动态初始化,此类静态变量的初始化不确定地排序,除非程序在初始化变量之前启动了线程,在这种情况下,其初始化是无序列的(自C ++ 17起)。相对于所有其他动态初始化,此类线程局部变量的初始化没有顺序。
我能找到的最佳答案是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()
)-您也可以使用私有结构,并为访问器的结果保持常量,因此例如,你可以做
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;
};