G ++ compiler cannot compile fully qualified types
I'm trying to use a static instance of a struct in the same struct, but the g ++ compiler tells me that:
C:\Temp\cs2cpp_tries\test\test.cpp: In instantiation of 'struct Static<Test<int> >':
C:\Temp\cs2cpp_tries\test\test.cpp:16:19: required from 'struct Test<int>'
C:\Temp\cs2cpp_tries\test\test.cpp:20:12: required from here
C:\Temp\cs2cpp_tries\test\test.cpp:6:4: error: 'Static<T>::t' has incomplete type
T t;
^
C:\Temp\cs2cpp_tries\test\test.cpp:10:8: note: declaration of 'struct Test<int>'
struct Test
^~~~
Here's some sample code. You can see the types are defined, but g ++ doesn't like it anyway.
#include <iostream>
template < typename T >
struct Static
{
T t;
};
template < typename T >
struct Test
{
static Static<Test<T>> t;
};
template < typename T >
Static< Test<T> > Test<T>::t;
int main (int argc, char **argv)
{
Test<int> t;
return 0;
}
But if you remove template < typename T >
from the test class and the code becomes fully compileable
#include <iostream>
template < typename T >
struct Static
{
T t;
};
struct Test
{
static Static<Test> t;
};
Static< Test > Test::t;
int main (int argc, char **argv)
{
Test t;
return 0;
}
source to share
Looks like a gcc error, from [class.static]
A non-standard static data member declaration in its class definition is not a definition and may be of incomplete type other than cv void.
Therefore, whether it is a type Test<T>
or a Static<Test<T>>
complete type, the declaration must be allowed.
From [temp.inst]
a class template specialization is implicitly created when the specialization is referenced in a context that requires a fully qualified object type
Implicit instantiation of template template specialization causes implicit creation of declarations, but not definitions, [...] static data members [...]
This means that when we first use Test<int>
to declare a variable, Test<int>
it is required to be a fully-qualified type, so it is Test<int>
implicitly created, but Static<Test<int>>
not fully required, a specific type of the object, since it is still only declared.
Funnily enough, gcc compiles this just fine
template<typename>
struct Static;
template<typename T>
struct Test
{
static Static<Test<T>> t;
};
template<typename T>
Static<Test<T>> Test<T>::t;
Test<int> t;
//auto u = t.t; // error, now requires a completely-defined type
Even if Static
not defined, Test::t
it should never be a fully qualified type.
source to share