Search code examples
c++c++11templatesvariadic-templatestype-alias

How come? aliases not detected in trait


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>>{});
}

Solution

  • Temp is deduced twice when you try to match the partial specialization:

    • By matching Temp against AT. This trivially deduces Temp to be AT.
    • By matching 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.