Alw*_*ing 5 c++ initialization static-variables
我知道来自不同翻译单元的静态变量初始化顺序的问题.但是,我的问题是在一个翻译单元内,事实上,在一个结构中:
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;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
Entered computeAllMDDeltas
Exiting computeAllMDDeltas
computeAllActions
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,computeAllMDDeltas之前被调用过computeAllActions,因此allActions_在使用时没有被初始化computeAllMDDeltas.有趣的是,computeAllActions即使在allActions_使用时也不会被调用computeAllMDDeltas.
为什么会发生这种情况?在这种情况下建议的方式是什么?
为什么在定义静态成员变量时不遵循定义顺序?
因为标准说初始化是无序的:
[basic.start.init]/2(N4140标准草案)
...显式专用类模板的定义静态数据成员已经有序初始化.其他 类模板静态数据成员(即,隐式或显式实例化的特化)具有无序初始化....
在这种情况下建议的方式是什么?
与翻译单元的初始化相同:构造首次使用成语:
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;
}
};
Run Code Online (Sandbox Code Playgroud)