Risking getting flagged for duplication, I take my chances. Consider the following:
Given the following static const arrays arrA and arrB, arrB depending on 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;
}
If I understand correctly, this is a case of unordered initialization of static const member as given in the standard:
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.
The best answer I could find is here but makes no mention of whether there's a known pattern allowing to perform such initialization in an ordered way. Is that even possible while keeping static const
?
Ideally I'd like the arrays to remain const
, otherwise the problem is trivial.
Though this example could be built with constexpr
, in a real-world case dynamic initialization is required (I use <random>
).
Edit: I find it interesting that no matter the order of declaration or definition in the source, arrB
gets initialized before arrA
.