Why isnโ€™t the determination procedure performed when defining static member variables?

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

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; } 

Output:

 Entered computeAllMDDeltas Exiting computeAllMDDeltas computeAllActions 

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

Why is this happening and what is the recommended way in this situation?

+5
source share
1 answer

Why doesnโ€™t the order of definition be defined when defining static member variables?

Because the standard says initialization is disordered:

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

... Definitions of explicitly specialized classes of static elements of a template template ordered initialization. Other static members of the template template (i.e. implicitly or explicitly created instances) have unordered initialization ....


What is the recommended method in this situation?

Same as initialization between 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; } }; 
+5
source

Source: https://habr.com/ru/post/1264164/


All Articles