g ++编译器无法编译完全定义的类型

时间:2017-07-13 12:48:39

标签: c++ c++11

我试图在同一结构中使用struct的静态实例,但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
        ^~~~

这是代码示例。您可以看到已定义类型,但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;
}

但是如果从测试类中删除template < typename T >并且代码变得完全可编辑

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

1 个答案:

答案 0 :(得分:3)

似乎是来自[class.static]

的gcc错误
  

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

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

来自[temp.inst]

  

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

  

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

表示当我们第一次使用Test<int>声明变量时,Test<int>必须是完全定义的类型,因此Test<int>被隐式实例化,但Static<Test<int>>不是它必须是一个完全定义的对象类型,因为它仍然只是声明。

有趣的是,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

Live

即使Static未定义,Test::t也不需要是完全定义的类型。