The question is simple: look at the code. Both static asserts pass. I would not expect the second one to pass. Is this a bug or normal behavior?
#include <array>
#include <type_traits>
template <template <class...> class Temp, class Specialization>
struct IsSpecialization : std::false_type {};
template <template <class...> class Temp, class... Ts>
struct IsSpecialization<Temp, Temp<Ts...>> : std::true_type {};
template <class...Args>
struct A {};
template <class...Args>
using AT = A<Args...>;
int main() {
static_assert(IsSpecialization<A, A<int>>{});
static_assert(!IsSpecialization<AT, AT<int>>{});
}
Temp
is deduced twice when you try to match the partial specialization:
Temp
against AT
. This trivially deduces Temp
to be AT
.Temp<Ts...>
against AT<int>
. This deduces Temp
to be A
because AT<int>
is equivalent to A<int>
, and this deduction will never deduce an alias template (see [temp.alias]/2).The overall deduction succeeds - and the partial specialization is a match - iff the two deductions give Temp
the same value, i.e., iff AT
and A
are considered to be equivalent. Whether they are is currently an open question.