Oui, votre utilisation de la fonction membre dans la liste d'initialisation est valide et conforme à la norme.
Les membres de données sont initialisés dans l'ordre de leur déclaration (et c'est la raison pour laquelle ils doivent apparaître dans la liste d'initialisation dans l'ordre de leur déclaration - la règle que vous avez suivie dans votre exemple). N_
est initialisé en premier et vous pourriez avoir transmis ce membre de données à fill_arr
. fill_arr
est appelée avant le constructeur, mais comme cette fonction n'accède pas aux membres de données non initialisés (elle n'accède pas du tout aux membres de données), son appel est considéré comme sûr.
Voici quelques excepts pertinentes de la dernière version (N3242 = 11-0012) de la norme du C:
§ 12.6.2.13: Les fonctions membres (y compris les fonctions de membres virtuels, 10.3) peuvent être appelées (...) Cependant, si ces opérations sont effectuées dans un ctor-initializer (ou dans une fonction appelée directement ou indirectement à partir d'un ctor-initialiseur) avant que tous les initialiseurs aient terminé, le résultat de l'opération est indéfini. Exemple:
class A { public: A(int); };
class B : public A {
int j;
public:
int f();
B() : A(f()), // undefined: calls member function
// but base A not yet initialized
j(f()) { } // well-defined: bases are all initialized
};
class C {
public:
C(int);
};
class D : public B, C {
int i;
public:
D() : C(f()), // undefined: calls member function
// but base C not yet initialized
i(f()) { } // well-defined: bases are all initialized
};
§12.7.1: Pour un objet avec un constructeur non triviale, en se référant à tout membre non-statique ou la classe de base de l'objet avant que le constructeur commence résultats d'exécution dans comportement indéfini. Exemple
struct W { int j; };
struct X : public virtual W { };
struct Y {
int *p;
X x;
Y() : p(&x.j) { // undefined, x is not yet constructed
}
};
La question est bonne, mais l'exemple de code est quelque peu artificielle. Qu'est-ce qui vous empêche de déclarer 'fill_arr' comme étant' static' et ne fait aucun doute que c'est légal? –
Serait-ce thread-safe? Je veux dire, il y a un vecteur local pour 'fill_arr', si c'est static, dois-je le protéger par une sorte de mutex? –
Le 'std :: vector arr' a _automatic storage_, donc il y aurait une instance pour chaque invocation de la fonction' fill_arr'. C'est basique _C++ _... –