Comment se fait-il que l’ordre de définition ne soit pas suivi lors de la définition de variables de membre statique?

Je connais le problème de l’ordre d’initialisation des variables statiques provenant de différentes unités de traduction. Cependant, mon problème est dans une unité de traduction et, en fait, dans une structure:

template  struct SlidingTile { using AllActions = std::array; using AllMDDeltas = std::array; 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  const typename SlidingTile::AllActions SlidingTile::allActions_ = SlidingTile::computeAllActions(); template  const typename SlidingTile::AllMDDeltas SlidingTile::mdDeltas_ = SlidingTile::computeAllMDDeltas(); int main() { SlidingTile s; std::cout << s.mdDelta(2) << std::endl; return 0; } 

La sortie est:

 Entered computeAllMDDeltas Exiting computeAllMDDeltas computeAllActions 

À ma grande surprise, computeAllMDDeltas est appelé avant computeAllActions . allActions_ conséquent, allActions_ n’est pas initialisé lorsqu’il est utilisé dans computeAllMDDeltas . Fait intéressant, computeAllActions n’est pas appelée même lorsque allActions_ est utilisé dans computeAllMDDeltas .

Pourquoi cela se produit-il et quelle est la méthode conseillée dans cette situation?

Comment se fait-il que l’ordre de définition ne soit pas suivi lors de la définition de variables de membre statique?

Parce que la norme dit que l’initialisation n’est pas ordonnée:

[basic.start.init] / 2 (projet de norme N4140)

… Les définitions des membres de données statiques de modèle de classe explicitement spécialisés ont ordonné leur initialisation. Les autres membres de données statiques de modèle de classe (c’est-à-dire les spécialisations implicitement ou explicitement instanciées) ont une initialisation non ordonnée . …


Quelle est la manière conseillée dans cette situation?

Identique à l’initialisation sur plusieurs unités de traduction: Construire lors de la première utilisation idiome:

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