C++ g++;编译器可以';不编译完全定义的类型

C++ g++;编译器可以';不编译完全定义的类型,c++,c++11,C++,C++11,我试图在同一个结构中使用结构的静态实例,但g++编译器告诉我: 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:

我试图在同一个结构中使用结构的静态实例,但g++编译器告诉我:

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
        ^~~~
C:\Temp\cs2cpp\u tries\test\test.cpp:在“struct Static”的实例化中:
C:\Temp\cs2cpp\u tries\test\test.cpp:16:19:结构测试中需要
C:\Temp\cs2cpp\u tries\test\test.cpp:20:12:此处为必填项
C:\Temp\cs2cpp\u tries\test\test.cpp:6:4:错误:“Static::t”的类型不完整
T;
^
C:\Temp\cs2cpp\u tries\test\test.cpp:10:8:注意:“结构测试”的声明
结构测试
^~~~
下面是代码示例。您可以看到类型已经定义,但是g++仍然不喜欢它

#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;
}
#包括
模板
结构静态
{
T;
};
模板
结构测试
{
静态t;
};
模板
静态<测试>测试::t;
int main(int argc,字符**argv)
{
试验t;
返回0;
}
但如果您从测试类中删除
模板
,代码就可以完全编译

#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;
}
#包括
模板
结构静态
{
T;
};
结构测试
{
静态t;
};
静态<测试>测试::t;
int main(int argc,字符**argv)
{
试验t;
返回0;
}

看起来像是一个gcc错误,从

非内联静态数据成员在其类定义中的声明不是定义,可能是cv void以外的不完整类型

因此,无论
Test
还是
Static
是否具有完整类型,都应该允许声明

当在需要完全定义的对象类型的上下文中引用专门化时,类模板专门化将隐式实例化


类模板专门化的隐式实例化导致声明的隐式实例化,而不是定义的隐式实例化,[…]静态数据成员[…]

这意味着当我们第一次使用
Test
声明变量时,
Test
需要是一个完全定义的类型,因此
Test
被隐式实例化,但是
Static
不需要是一个完全定义的对象类型,因为它仍然只被声明

有趣的是,gcc编译的很好

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
模板
结构静态;
模板
结构测试
{
静态t;
};
模板
静态试验:t;
试验t;
//自动u=t.t;//错误,现在需要完全定义的类型


即使
Static
甚至没有定义,
Test::t
永远不需要是一个完全定义的类型。

它需要是一个引用或指针类型。是的,它在完全定义之前不能被安装。只要从测试类中删除“template,它就会被完全编译。下面是一个示例:
#include templatestruct Static{T;};结构测试{static static t;};静态<测试>测试::t;intmain(intargc,char**argv){Test t;return 0;}
在我看来像是一个gcc错误。我同意你的看法。我看不出有任何理由不编译代码如果你将静态声明放入测试一,代码将是可编译的:)@Alexander77我不知道是什么导致gcc这么做,但它的错误消息既神秘又不符合上面的引号;代码不仅仅使用类型;它使用的是模板,谈论不完整的类型并不能解决不完整的模板。@路人——说清楚,我并不是说你的结论是错误的。我还没有涉足其中,现在没有精力。我们可以考虑代码完全由微软C++编译器编译,因此类型和模板是否完成?