I was reading the spec and found that it appears to apply a "wording trick" here, to make a function viable but render the call illformed (as we know from several other cases, for example with lvalue references to bitfield, yet there the trick is more obvious):

"[Note 1:
Aggregate initialization does not require that the members are declared in designation order.
If, after overload resolution, the order does not match for the selected overload, the initialization of the parameter will be ill-formed ([dcl.init.list])."

(this follows from the normative wording for the simple non-nesting case.. I take the note because it clears the air here and shows the intention).

However, as [dcl.init.aggr] notes (and again it follows from the normative wording anyway), if a member is initialized by {...} again, then the rules of list initialization applies. Therefore I think that [dcl.init.aggr] applies constraints on the order of members indirectly:

"[Note 3:
If an initializer is itself an initializer list, the element is list-initialized, which will result in a recursive application of the rules in this subclause if the element is an aggregate.
— end note]"

I take all this to mean that the nested case is to be treated differently than the non-nested case, if going by the letter of the spec, but the implementations I tried (gcc and clang) treat the followinig example as being ambiguous, rather than selecting "C<B>":

struct A {
   int x; int y;

struct B {
   int y; int x;

template<typename T>
struct C {
  T a;

void f(C<A> a);
void f(C<B> b);

int main() {
   f({{ .y = 1, .x = 2}});