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.]
SameName
used in the function parameter type, name lookup finds the member name::Outer::SameName
instead of the template parameter nameSameName
. However, I cannot seem to pinpoint the standard wording which would indicate correct lookup results here. – Leasebackstruct Outer
withnamespace Outer
and things work fine. What should be the reason for the standard, to restrict the choice of template type names for inner classes (2nd query)? – Heilbronn