我正在尝试尽可能多地使用前向声明来最小化编译时间。我注意到当我转发声明一个使用类似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”时,这工作正常,为什么?
答案 0 :(得分:6)
这是因为编译器需要知道要存储在向量中的类型的大小。没有完整的类定义,它无法知道这一点。
另一种方法是存储指向前向声明类型的指针 - 但是你需要管理内存分配和释放。
第三种选择是根据您的前向声明类型声明shared_ptr
类型,并将它们存储在您的向量中。
答案 1 :(得分:0)
正如错误所说
error C2036: 'myTypeA *' : unknown size
编译器不会通过前向声明知道此类对象的大小。它只是告诉它是什么类型。您需要包含标头以引入类定义,以便编译器可以评估此类对象的大小。
请参阅此SO question
答案 2 :(得分:-1)
简单的答案是该标准需要完整的定义 任何时候你在一个类型上实例化模板;这是未定义的行为 除此以外。强制执行此类约束的编译器(g ++,当你 用适当的选项编译)将无法编译。其他人可能 接受。 (虽然形式上未定义的行为,但在实践中,它会 要么无法编译,要么按预期工作。)
微软无法编译代码,我感到有些惊讶
你发布了,因为它不需要知道myTypeA
的任何信息。该
消息看起来像是在调用时可能出现的内容
功能;如果你调用这个函数,你肯定需要一个定义
myTypeA
,因为编译器必须实例化副本
构造函数,反过来意味着复制包含的实例
myTypeA
。