定义静态成员变量时,为什么不遵循定义顺序? [英] How come the definition order is not followed when defining static member variables?

查看:75
本文介绍了定义静态成员变量时,为什么不遵循定义顺序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道来自不同翻译单元的静态变量的初始化顺序问题.但是,我的问题是在一个翻译单元内,实际上是在一个结构内:

I know about the problem of the order of initialization of static variables from different translation units. However, my problem is within one translation unit and, in fact, within one struct:

template <int size>
struct SlidingTile {
    using AllActions = std::array<int, size>;
    using AllMDDeltas = std::array<int, size>;

    int mdDelta(int i) const {
        return mdDeltas_[i];
    }

    static AllActions computeAllActions() {
        std::cout << "computeAllActions" << std::endl;
        AllActions res;
        for (int i = 0; i < size; ++i) res[i] = i;
        return res;
    }

    static AllMDDeltas computeAllMDDeltas() {
        std::cout << "Entered computeAllMDDeltas" << std::endl;
        AllActions res;
        for (int i = 0; i < size; ++i) res[i] = 10 * allActions_[i];
        std::cout << "Exiting computeAllMDDeltas" << std::endl;
        return res;
    }

private:
    static const AllActions allActions_;
    static const AllMDDeltas mdDeltas_;
};

template <int size>
const typename SlidingTile<size>::AllActions
    SlidingTile<size>::allActions_ = SlidingTile<size>::computeAllActions();

template <int size>
const typename SlidingTile<size>::AllMDDeltas
    SlidingTile<size>::mdDeltas_ = SlidingTile<size>::computeAllMDDeltas();

int main() {
    SlidingTile<3> s;
    std::cout << s.mdDelta(2) << std::endl;
    return 0;
}

输出为:

Entered computeAllMDDeltas
Exiting computeAllMDDeltas
computeAllActions

令我惊讶的是,computeAllMDDeltascomputeAllActions之前被调用,因此allActions_computeAllMDDeltas中使用时未初始化.有趣的是,即使在computeAllMDDeltas中使用了allActions_,也不会调用computeAllActions.

To my surprise, computeAllMDDeltas gets called before computeAllActions and so allActions_ is not initialized when it is used in computeAllMDDeltas. Interestingly, computeAllActions is not called even when allActions_ is used in computeAllMDDeltas.

为什么会发生这种情况,在这种情况下建议采取什么方法?

Why does this happen and what is the advised way in this situation?

推荐答案

为什么在定义静态成员变量时不遵循定义顺序?

How come the definition order is not followed when defining static member variables?

因为该标准说初始化是无序的:

Because the standard says that the initialization is unordered:

[basic.start.init]/2(N4140标准草案)

[basic.start.init] /2 (N4140 standard draft)

...显式专门的类模板静态数据成员的定义已按顺序进行初始化.其他 类模板静态数据成员(即,隐式或显式实例化的专业化)没有顺序 初始化. ...

... Definitions of explicitly specialized class template static data members have ordered initialization. Other class template static data members (i.e., implicitly or explicitly instantiated specializations) have unordered initialization. ...


在这种情况下,建议的方法是什么?

what is the advised way in this situation?

与跨翻译单元的初始化相同:在首次使用时进行构建惯用语:

Same as initialization across translation units: Construct On First Use idiom:

struct SlidingTile {
    // ...
private:
    static const AllActions& allActions() {
        static const AllActions instance = computeAllActions();
        return instance;
    }
    static const AllMDDeltas& mdDeltas() {
        static const AllMDDeltas instance = computeAllMDDeltas();
        return instance;
    }
};

这篇关于定义静态成员变量时,为什么不遵循定义顺序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆