(All ISO Standard references below refer to N4659: March 2017 post-Kona working draft/C++17 DIS, and all example program results are consistent over GCC and Clang for C++11, C++14 and C++17)
I believe GCC is wrong here, but I haven't been able to find a corresponding (open) GCC bug report.
[temp.class.order]/1 covers the partial ordering of class template specializations [emphasis mine]:
For two class template partial specializations, the first is more
specialized than the second if, given the following rewrite to two
function templates, the first function template is more specialized
than the second according to the ordering rules for function
templates:
- (1.1) Each of the two function templates has the same template parameters as the corresponding partial specialization.
- (1.2) Each function template has a single function parameter whose type is a class template specialization where the template arguments
are the corresponding template parameters from the function template
for each template argument in the template-argument-list of the
simple-template-id of the partial specialization.
Thus, for analyzing ordering, we re-write the class template specializations as function templates, as per above:
// G)
template<template<typename...> typename AggregateType,
typename Base,
typename... Bases1,
typename... Bases2>
void f(MyClass<AggregateType,
AggregateType<Bases1...>,
AggregateType<Base, Bases2...>>);
// F)
template<template<typename...> typename AggregateType,
typename Base,
typename... Bases1>
void f(MyClass<AggregateType, AggregateType<Bases1...>, AggregateType<Base>>);
The partial ordering of the G and F overloads of f is governed by [temp.func.order]/2, [temp.func.order]/3 and [temp.func.order]/4 [emphasis mine]:
[temp.func.order]/2
Partial ordering selects which of two function templates is more
specialized than the other by transforming each template in turn
(see next paragraph) and performing template argument deduction
using the function type. The deduction process determines whether
one of the templates is more specialized than the other. If so, the
more specialized template is the one chosen by the partial ordering
process.
[temp.func.order]/3
To produce the transformed template, for each type, non-type, or
template template parameter (including template parameter packs
thereof) synthesize a unique type, value, or class template
respectively and substitute it for each occurrence of that parameter
in the function type of the template. [...]
[temp.func.order]/4
Using the transformed function template's function type, perform type deduction against the other template as described in [temp.deduct.partial]. [...]
Thus, to produce the transformed template for the two f overloads above, specifically considering the template template parameter AggregateType (as used in both overloads) and the instantiation of these overloads with the particular class template Aggregate and classes Foo and Bar,
template<typename ... Bases>
struct Aggregate : Bases...
{ };
class Foo {};
class Bar {};
used as arguments for the template template parameter and template parameters, respectively, we may without loss of generality consider the following (partially) transformed function templates as argument templates when continuing the analysis of the partial ordering of the original class templates:
// G-transformed (argument template>
template<typename... Bases2>
void f(MyClass<Aggregate, Aggregate<Foo, Bar>, Aggregate<Foo, Bases2...>>);
// F-transformed (argument template>
void f(MyClass<Aggregate, Aggregate<Foo, Bar>, Aggregate<Foo>>);
From [temp.deduct.partial]/2, [temp.deduct.partial]/10 and [temp.deduct.partial]/11 [extracts, emphasis mine]:
[temp.deduct.partial]/2
Two sets of types are used to determine the partial ordering. For each
of the templates involved there is the original function type and the
transformed function type. [...] The deduction process uses the
transformed type as the argument template and the original type of
the other template as the parameter template.
[temp.deduct.partial]/10
Function template F is at least as specialized as function template G if, for each pair of types used to determine the ordering, the type from F is at least as specialized as the type from G. F is more specialized than G if F is at least as specialized as G and G is not at least as specialized as F.
[temp.deduct.partial]/11
If, after considering the above, function template F is at least as specialized as function template G and vice-versa, and if G has a trailing parameter pack for which F does not have a corresponding parameter, and if F does not have a trailing parameter pack, then F is more specialized than G.
it follows that that F is at least as specialized as G (/10), and moreover that F is more specialized than G due to the (additional) trailing parameter pack Bases2 that is present in G but not in F (/11). It may even be possible to directly apply the second part of [temp.deduct.partial]/10 to argue that F is more specialized than G as Aggregate<Foo> is more specialized than Aggregate<Foo, Bases2...>>.
Either way, either per /10 and /11, or per /10 alone, the Specialized alias
using Specialized = MyClass<Aggregate, Aggregate<Foo, Bar>, Aggregate<Foo>>;
refers non-ambigiously to the "second specialization" (from OPs post) of MyClass, specifically the specialization that was re-written to the F function template above, as this class template specialization is more specialized than the "first specialization" (the one with the additional Bases2 variadic template parameter pack).