I have the following code:
struct test
{
static void T()
{
}
template<typename T>
void f(T* t)
{
}
template<typename T>
T* get()
{
return new T();
}
};
int main()
{
test t;
t.f(t.get<int>());
return 0;
}
This code compiles fine as it is, but if I move the definition outside the class it doesn't:
struct test
{
static void T();
template<typename T>
void f(T* t);
template<typename T>
T* get();
};
void test::T()
{
}
template<typename T>
void test::f(T* t)
{
}
template<typename T>
T* test::get()
{
return new T();
}
int main()
{
test t;
t.f(t.get<int>());
return 0;
}
gcc error message:
#1 with x86-64 gcc 9.3
<source>:17:14: error: variable or field 'f' declared void
17 | void test::f(T* t)
| ^
<source>:17:15: error: expected primary-expression before '*' token
17 | void test::f(T* t)
| ^
<source>:17:17: error: 't' was not declared in this scope
17 | void test::f(T* t)
| ^
Compiler returned: 1
clang error message:
#1 with x86-64 clang 8.0.0
<source>:17:12: error: variable has incomplete type 'void'
void test::f(T* t)
^
<source>:17:17: error: use of undeclared identifier 't'
void test::f(T* t)
^
<source>:17:19: error: expected ';' at end of declaration
void test::f(T* t)
^
;
<source>:18:1: error: expected unqualified-id
{
^
<source>:24:16: error: unknown type name 'T'
return new T();
^
5 errors generated.
Compiler returned: 1
MSVC 2019 error message:
#1 with x64 msvc v19.24
example.cpp
<source>(17): error C2065: 't': undeclared identifier
<source>(17): error C2182: 'f': illegal use of type 'void'
<source>(17): error C2350: 'test::f' is not a static member
<source>(17): note: see declaration of 'test::f'
<source>(17): error C2513: 'test::f': no variable declared before '='
<source>(18): error C2447: '{': missing function header (old-style formal list?)
Compiler returned: 2
It also compiles fine if it change typename T to typename SomeOtherName in test::f or if I rename static void T() to something else.
Can you please explain me why the first version compiles and the second doesn't? Can you point me to the standard wording for this error?
EDIT: I've posted error message from different compilers. As @cigien pointed clang trunk compiles the second version