Why compilation fails when a template parameter name matches an inner class name?

269 views Asked by At

Following compiles perfectly fine:

struct MyClass {
  template<typename SameName>
  void foo (SameName* p);
};
struct SameName {};

template<class SameName>
void MyClass::foo (SameName* p) {}

However, if we enclose MyClass and SameName inside some class Outer then the template function defined outside, fails to compile.

struct Outer {
  /* paste here `MyClass` & `SameName` from above */
};

template<class SameName>
void Outer::MyClass::foo (SameName* p) {}  // <--- error here
//   ^^^^^

The g++ (03-14) error is weird:

error: prototype for ‘void Outer::MyClass::foo(Outer::SameName*)’ does not match any in class ‘Outer::MyClass’
 void Outer::MyClass::foo (SameName* p) {}
      ^~~~~
templateClassMethod.cpp:6:10: error: candidate is: template<class SameName> void Outer::MyClass::foo(SameName*)
     void foo (SameName* p);

The clang (03-14) error is less intuitive:

error: out-of-line definition of 'foo' does not match any declaration in 'Outer::MyClass'
void Outer::MyClass::foo (SameName* p) {}

Question:

  • Is this a language/compiler bug or an expected behaviour?
  • If expected, then why is the choice for template type's name being restricted for inner classes?

[Note: Actually I had many template parameters, and incidentally one of them matched the inner class name, by chance. It took me 1 hour to figure out. The error generated in that complex scenario was totally misleading.]

0

There are 0 answers