out-of-order designated initialization, nested designated initialization, mixing of designated initializers and regular initializers, and designated initialization of arrays are all supported in the C programming language, but are not allowed in C++. https://en.cppreference.com/w/cpp/language/aggregate_initialization
To be consistent with list-initialization, we expect the initializers to be evaluated in left-to-right order, as written; but we also want to perform the actual initializations in data members' declaration order, so that they can be destructed in the reverse order. When these two orders do not match, an implementation cannot avoid creating temporaries to fill the gap between the evaluations and initializations.
To meet these expectations for guaranteed copy elision, we require the designators to appear as a subsequence of the data member declaration sequence, so that the evaluation order matches the declaration order, and it is also textually left-to-right in designated initialization. https://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0329r0.pdf
They could have simply copied C#'s solution. In C#,
1 2 3 4
var foo = new Foo{
Bar = new Bar(),
Baz = new Baz(),
};
is exactly equivalent to
1 2 3
var foo = new Foo()
foo.Bar = new Bar();
foo.Baz = new Baz();
even if Foo.Foo() initializes Foo.Bar and Foo.Baz to something else. Yeah, it might have required extra constructions, but in this end this is just syntactic sugar. The alternative previously would have been to do
Is there a name for the concept you just demonstrated here? I see that it's assigning 5 to the outer x, but I can't fathom how it's interpreting that last pair of parentheses before the semi-colon.
The issue, of course, with in-order designated initialisation is that you need to know the name/ordering specified in the definition. Intellisense (at least in MS) is of no use here as it displays in sorted alpha order - not the object order. If constructor initialisations can be written in any order but evaluated in definition order, then why not designated initialisation be the same...
Yeah I meant braces. But, okay now I get it. The assignment is the expression itself, and the return value of the assignment is then also initializing the inner x.