c++template-specialization

Is explicit specialization of a class template via a using alias supposed to work?


Fist of all, what I'm doing seems to work on all of GCC/Clang/MSVC/icc/etc, so my question is; is that by accident or does the standard require it to be allowed?

In one way it seems like a logical extension of stuff, but on the other hand the syntax just looks strange enough that I'm concerned I'm wondering off into depending-on-bugs territory:

#include <type_traits>

template <int, bool>
void Bar();

template <int i>
struct A {
    struct T : std::true_type {};
    static void Foo() { Bar<i, T::value>(); }
};

// The normal way to do thing:
template <> struct A<1>::T : std::false_type {};

// But this also seems to work despite looking very odd:
using A3 = A<3>;
template <> struct A3::T : std::false_type {};

void Go() {
    A<0>::Foo();  // Calls Bar<0, true>()
    A<1>::Foo();  // Calls Bar<1, false>()
    A<2>::Foo();  // Calls Bar<2, true>()
    A<3>::Foo();  // Calls Bar<3, false>()
}

Solution

  • It is ill-formed.

    See [temp.spec.general]/3:

    In an explicit specialization declaration for [...] a member of a class template [...] the variable or class that is explicitly specialized shall be specified with a simple-template-id.

    A3 is not a simple-template-id.