https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85054
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2018-03-23 Ever confirmed|0 |1 --- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> --- Confirmed. The problem was in <functional>, which was included by <string>, and if GCC had caught it I wouldn't have committed the bug. G++ does diagnose it if you try to use it: struct Y { using type = int; }; X<Y, void> x; I was initially surprised that the X<T, void_t<typename T::type>> partial specialization isn't more specialized than the X<T, void> one, but it's not. Given that, GCC should diagnose it. FWIW the reduced example isn't very realistic, the real case used a default argument: template<typename ... > using void_t = void; template<typename, typename = void> struct X; template<typename T> struct X<T, void_t<typename T::type>> {}; template<typename T> struct X<T, void> {}; I expected the second partial specialization to be more specialized than the first, and for it to be valid, just like the fixed code: template<typename ... > using void_t = void; template<typename, typename = void> struct X {}; template<typename T> struct X<T, void_t<typename T::type>> {}; Now when T::type is not valid we use the primary template to generate the specialization X<T, void>, but when T::type is valid the partial specialization is more specialized than the primary template.