Il dépend.
Tout d'abord, supposons que x++
lui-même, ne pas se prévaloir d'un comportement indéfini. Pensez signé débordement, incrémentation d'un passé-la-fin-pointeur, ou le suffixe-increment opérateur peut être défini par l'utilisateur).
En outre, supposons que l'invocation f()
et g()
avec leurs arguments et de détruire les temporaires ne pas se prévaloir d'un comportement indéfini.
Qui sont tout à fait beaucoup d'hypothèses, mais si elles sont cassées la réponse est triviale.
Maintenant, si la virgule est le haut-virgule-opérateur, la virgule dans un arc-boutée-initialisation de la liste ou de la virgule dans un mem-initialiseur de liste de, la gauche et la droite sont séquencés que ce soit avant ou après les uns des autres (et vous savez qui), afin de ne pas interférer, rendant le comportement bien défini.
struct X {
int f, g;
explicit X(int x) : f(x++), g(x++) {}
};
// Demonstrate that the order depends on member-order, not initializer-order:
struct Y {
int g, f;
explicit Y(int x) : f(x++), g(x++) {}
};
int y[] = { f(x++), g(x++) };
Si, au contraire, x++
invoque un opérateur défini par l'utilisateur-surcharge pour postfix-incrémentation, vous avez une période indéterminée le séquençage des deux instances de l' x++
, et donc un comportement non spécifié.
std::list<int> list{1,2,3,4,5,6,7};
auto x = begin(list);
using T = decltype(x);
void h(T, T);
h(f(x++), g(x++));
struct X {
X(T, T) {}
}
X(f(x++), g(x++));
Et dans le dernier cas, vous obtenez complet à un comportement indéfini comme les deux postfix-incréments de x
sont séquencé.
int x = 0;
void h(int, int);
h(f(x++), g(x++));
struct X {
X(int, int) {}
}
X(f(x++), g(x++));