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!

Reply via email to