Votre deuxième cas, c'est un comportement indéfini, vous n'êtes plus globale de l'initialisation, il est encore initialisation de la liste, mais dans ce cas, vous avez un utilisateur défini par le constructeur, qui est appelé. Afin de passer le deuxième argument de votre constructeur, il doit évaluer foo.i
mais il n'est pas initialisé pourtant, puisque vous n'avez pas encore entré dans le constructeur et, par conséquent, vous produisez une durée indéterminée de la valeur et de la production d'une valeur indéterminée est un comportement indéfini.
Nous avons également la section 12.7
de la Construction et de la destruction [de classe.cdtor] qui dit:
Pour un objet avec un non-trivial constructeur, se référant à un non-membre statique ou de la classe de base de l'objet
avant que le constructeur commence l'exécution entraîne un comportement non défini [...]
Donc je ne vois pas une façon d'obtenir votre deuxième exemple de travail comme ton premier exemple, en supposant que le premier exemple est bien valide.
Votre premier cas semble que ce devrait être bien définis, mais je ne peux pas trouver une référence dans le projet de norme qui semble la rendre explicite. C'est peut-être un défaut mais sinon, ce serait un comportement indéfini car la norme ne définit pas le comportement. Ce que la norme ne nous disent, c'est que les initialiseurs sont évaluées dans l'ordre et les effets secondaires sont séquencés, à partir de la section 8.5.4
[dcl.init.liste]:
Au sein de l'initialiseur de liste d'un arc-boutée-init-liste, l'initialiseur-clauses, y compris d'éventuelles résultant de pack
les expansions (14.5.3), sont évaluées dans l'ordre dans lequel ils apparaissent. Qui est, à chaque valeur de calcul et de
des effets secondaires liés à un initialiseur de la clause est séquencée avant chaque valeur de calcul et de côté
effet associé à toute l'initialiseur de la clause qui le suit dans la liste séparée par des virgules de l'initialiseur de la liste. [...]
mais nous n'avons pas de texte explicite en disant les membres sont initialisées après chaque élément est évalué.
On pourrait dire que dans la classe membre initialise semble forcer les membres à être initialisé comme la liste est évalué comme T. C. souligne cet exemple le C++14 projet de norme un peu implique ceci:
Si il y a moins d'initialiseur-clauses dans la liste qu'il y a de
les membres de l'ensemble, puis chaque membre n'est pas explicitement initialisée
doit être initialisé à partir de son corset ou égal initialiseur ou, s'il y
est pas de corset-ou-equalinitializer, du vide d'une liste d'initialiseur
(8.5.4). [ Exemple:
struct S { int a; const char* b; int c; int d = b[a]; };
S ss = { 1, "asdf" };
initialise ss.une avec 1, ss.b avec "asdf", ss.c avec la valeur d'un
expression de la forme int{} (qui est, 0), et ss.d avec la valeur
de ss.b[ss.a] (c'est - 's'),
Cet exemple a été amené par N3653 mais aucune explication n'est fournie pour l'exemple et puisque les exemples sont non-normatifs, nous devons prendre cela avec un grain de sel. Avant C++14 agrégat intialization n'a pas été autorisée lorsque dans la classe des membres intialization était présent.
Bien que si l'on accepte cette interprétation, il n'est pas clair, il s'appliquerait à C++11 car le texte est directement attribuable à un changement qui s'applique à C++14, mais pas à C++11.
MSalters fait valoir que la section 1.9
qui dit:
L'accès à un objet désigné par un volatile glvalue (3.10), la modification d'un objet, l'appel d'une bibliothèque d'e/S
la fonction, ou l'appel d'une fonction qui ne prend aucun de ces opérations sont tous les effets secondaires, qui sont des changements dans la
l'état de l'environnement d'exécution. [...]
combiné avec:
[...]très valeur de calcul et des effets secondaires liés à un initialiseur de la clause est séquencée avant chaque calcul de la valeur et des effets secondaires associés avec toute l'initialiseur de la clause qui suit [...]
Est suffisante pour garantir à chaque membre de l'agrégat est initialisé comme les éléments de la liste d'initialiseur sont évalués.
Pour référence, si la norme n'impose pas une exigence le comportement n'est pas défini à partir de la section 1.3.24
qui définit un comportement indéfini:
le comportement pour lequel la présente Norme Internationale n'impose pas d'exigences
[ Note: un comportement Indéfini peut être prévu lorsque la présente Norme Internationale omet aucune définition explicite de
comportement ou [...]
un comportement indéfini n'a pas besoin d'un diagnostic, d' 1.4
:
L'ensemble de diagnostiquer les règles se compose de tous syntaxique et sémantique des règles dans la présente Norme Internationale à l'exception de
pour que ces règles contenant une notation explicite que "aucun diagnostic n'est requis" ou qui sont décrits comme
résultant dans "un comportement indéfini."