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;
}

      

+3


source to share


1 answer


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

      

Live

Even if Static

not defined, Test::t

it should never be a fully qualified type.

+3


source







All Articles