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>()
}
It is ill-formed.
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.