为什么定义静态成员变量时不遵循定义顺序?
How come the definition order is not followed when defining static member 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;
}
输出为:
Entered computeAllMDDeltas
Exiting computeAllMDDeltas
computeAllActions
令我惊讶的是,computeAllMDDeltas
在 computeAllActions
之前被调用,因此 allActions_
在 computeAllMDDeltas
中使用时未被初始化。有趣的是,即使在 computeAllMDDeltas
.
中使用 allActions_
也不会调用 computeAllActions
为什么会发生这种情况,在这种情况下建议的方法是什么?
How come the definition order is not followed when defining static member variables?
因为标准说初始化是无序的:
[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?
与跨翻译单元初始化相同:首次使用时构造 成语:
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;
}
};
我知道不同翻译单元的静态变量初始化顺序的问题。但是,我的问题出在一个翻译单元中,实际上是在一个结构中:
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
令我惊讶的是,computeAllMDDeltas
在 computeAllActions
之前被调用,因此 allActions_
在 computeAllMDDeltas
中使用时未被初始化。有趣的是,即使在 computeAllMDDeltas
.
allActions_
也不会调用 computeAllActions
为什么会发生这种情况,在这种情况下建议的方法是什么?
How come the definition order is not followed when defining static member variables?
因为标准说初始化是无序的:
[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?
与跨翻译单元初始化相同:首次使用时构造 成语:
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;
}
};