https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86193
Jason Merrill <jason at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |SUSPENDED --- Comment #2 from Jason Merrill <jason at gcc dot gnu.org> --- (In reply to Jonathan Wakely from comment #1) > (In reply to zhonghao from comment #0) > > I tried the latest g++, but it does not accept the code. BTW, clang++ > > accepts the code. Is this a recurring bug? > > No, it's rejected for a different reason, so it's not the same bug. > > It started to be rejected with r243868: > > Check that a partial specialization is more specialized. Indeed. [temp.class.spec]: The specialization shall be more specialized than the primary template (17.6.5.2). Checking that is equivalent to resolving the partial ordering of function templates in template <class T> struct identity { typedef T type; }; template <class T, typename T::type A> struct foo {}; template <class T1, typename T1::type A1> void fn(foo<T1,A1>) = delete; template <class T2, T2 A2> void fn(foo<identity<T2>,A2>); int main() { fn(foo<identity<int>,0>()); // error here } which, similarly, G++ (and EDG) rejects, and clang accepts. I think G++ is right here: when we try to deduce values for T1 and A1 in partial ordering, we deduce T1 to identity<T2>, but we can't deduce anything for A1 because we don't know that the types are compatible. You can work around that by changing your partial specialization to template <class T, typename identity<T>::type A> struct foo<identity<T>, A> {}; This does seem like an underspecified area in the standard.