2

我正在尝试尽可能多地使用前向声明来最小化编译时间。我注意到,当我转发声明一个使用 std::vector 之类的类作为成员对象的类时(此处的示例):

class myTypeA
class A
{
  A(){};
  ~A(){};
  std::vector<myTypeA > getTypeA();

}

我收到以下错误:

microsoft visual studio 9.0\vc\include\vector(1112) : error C2036: 'myTypeA *' : unknown size
1>        c:\program files\microsoft visual studio 9.0\vc\include\vector(1102) : while compiling class template member function 'bool std::vector<_Ty>::_Buy(unsigned int)'
1>        with
1>        [
1>            _Ty=myTypeA
1>        ]
1>        d:\cpp\A.h(15) : see reference to class template instantiation 'std::vector<_Ty>' being compiled
1>        with
1>        [
1>            _Ty=myTypeA
1>        ]

当我使用#include“myTypeA.h”时,这工作正常,为什么?

4

3 回答 3

6

这是因为编译器需要知道要存储在向量中的类型的大小。如果没有完整的类定义,它就无法知道这一点。

另一种方法是存储指向您的前向声明类型的指针 - 但是您需要管理内存分配和释放。

第三种选择是shared_ptr根据您的前向声明类型声明一个类型并将它们存储在您的向量中。

于 2012-07-03T07:42:29.027 回答
0

正如错误所说

error C2036: 'myTypeA *' : unknown size

编译器不会通过前向声明知道此类型对象的大小。它只是告诉它是什么类型。您需要包含标头以引入类定义,以便编译器可以评估此​​类型对象的大小。

看到这个问题

于 2012-07-03T08:17:58.163 回答
-1

简单的答案是,只要您在类型上实例化模板,该标准就需要完整的定义。否则它是未定义的行为。强制执行此类约束的编译器(g++,当您使用适当的选项编译时)将无法编译。其他人可能会接受它。(虽然形式上未定义行为,但在实践中,它要么无法编译,要么按预期工作。)

我对 Microsoft 无法编译您发布的那段代码感到有些惊讶,因为它不需要知道任何关于myTypeA. 如果您正在调用该函数,该消息看起来可能会出现;如果您调用该函数,您肯定需要 的定义myTypeA,因为编译器必须实例化复制构造函数,这反过来意味着复制 myTypeA.

于 2012-07-03T08:34:39.563 回答