[C ++模板中的静态const初始化顺序

问题描述 投票:2回答:1

冒着被标记为重复的风险,我抓住了机会。考虑以下内容:

给出以下静态常量数组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之前初始化。

c++ static initialization c++14 const
1个回答
0
投票

如果要保证初始化的顺序,则必须将两个数组都包装在一个结构中,并使用该结构的构造函数来初始化静态变量。 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;
};
© www.soinside.com 2019 - 2024. All rights reserved.