https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87841
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |rejects-valid --- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> --- That example was changed by DR 458 https://wg21.link/cwg458 GCC compiles it if C is not used in the parameter-list: template<class T> struct A { struct B { /* ... */ }; typedef void C; void f(); template<class U> void g(); }; template<class B> void A<B>::f() { B b; // A's B, not the template parameter } template<class B> template<class C> void A<B>::g() { B b; // A's B, not the template parameter C c; // the template parameter C, not A's C } So GCC finds the right C in the function body. EDG also compiles that. Clang doesn't: dr458.cc:14:5: error: variable has incomplete type 'A::C' (aka 'void') C c; // the template parameter C, not A's C ^ 1 error generated. However for the example as given in [temp.local] (as in comment 0) in the standard, none of the compilers I tried accept it, because C in the function parameter-list finds A<B>::C (aka void) not the function template parameter. GCC says: dr458.cc:12:42: error: no declaration matches 'void A<T>::g()' 12 | template<class B> template<class C> void A<B>::g(C) { | ^~~~ dr458.cc:5:26: note: candidate is: 'template<class T> template<class U> void A<T>::g(U)' 5 | template<class U> void g(U); | ^ dr458.cc:1:26: note: 'struct A<T>' defined here 1 | template<class T> struct A { | ^ EDG says: "dr458.cc", line 12: error: a parameter may not have void type template<class B> template<class C> void A<B>::g(C) { ^ "dr458.cc", line 12: error: declaration is incompatible with function template "void A<T>::g(U)" (declared at line 5) template<class B> template<class C> void A<B>::g(C) { ^ 2 errors detected in the compilation of "dr458.cc". Clang says: dr458.cc:12:48: error: out-of-line definition of 'g' does not match any declaration in 'A<T>' template<class B> template<class C> void A<B>::g(C) { ^ dr458.cc:14:5: error: variable has incomplete type 'A::C' (aka 'void') C c; // the template parameter C, not A's C ^ 2 errors generated. And VC++ says: <source>(12): error C2244: 'A<T>::g': unable to match function definition to an existing declaration <source>(12): note: see declaration of 'A<T>::g' <source>(12): note: definition <source>(12): note: 'void A<T>::g(void)' <source>(12): note: existing declarations <source>(12): note: 'void A<T>::g(U)' Compiler returned: 2 This makes me think the example in [temp.local] is wrong!