使用前向声明时如何修复“字段类型不完整”错误
Posted
技术标签:
【中文标题】使用前向声明时如何修复“字段类型不完整”错误【英文标题】:How to fix an "field has incomplete type" error when using a forward declaration 【发布时间】:2014-12-25 14:26:31 【问题描述】:此代码引发编译器错误error: field ‘fTarget’ has incomplete type
,如 cmets 中所述。为什么会这样?我只是分配那个字段,而不是做任何需要知道里面是什么的操作……还是我?也许它无法弄清楚复制构造函数?
class FSRVertex; //fwd
class FSREdge
public:
char fC;
FSRVertex fTarget; //compiler error
FSREdge(char c, FSRVertex target) : fC(c), fTarget(target) //compiler error
;
class FSRVertex
public:
boost::unordered_map<char, FSREdge> fOutEdges;
FSRVertex() : fOutEdges()
;
【问题讨论】:
【参考方案1】:要将 FSRVertex 对象作为类的成员,编译器需要知道其大小,因此需要查看其完整定义。
要么为你的类提供完整的定义,要么你可以存储一个指针(最好是智能指针),指向在构造函数中执行的对象的动态分配副本。您需要将类外的构造函数主体移动到提供完整定义的位置。这种方法在运行时效率较低。
【讨论】:
参考也可以。 @black 参考一般不会很好,因为会更改所有权。 @Slava 那是另一回事。我只是想指出,参考也可以解决这个问题,而不是是否建议这样做。 @black 从技术上讲是的,可以解决前向声明的问题。但是对于这个使用参考的具体示例,恕我直言,这不是一个好的答案 我想补充一点,您可以通过模板实现相同的目标。第一个示例 (rextester.com/TLPEJW28982) 将 A 声明为全局类,并在类模板定义之后定义它。作为一个优势,您不必担心在哪里定义 struct A 并避免耦合。第二个示例 (rextester.com/PJCD69132) 将 A 视为 B 的嵌套结构。它编译和运行良好的原因是因为在实例化模板时发生了两阶段查找。有关详细信息,请参阅 C++ 模板:完整指南,10.3.1 两阶段查找。【参考方案2】:您始终可以将FSRVertex
设为FSREdge
的模板参数。然后编译器必须等待计算FSREdge
的大小,直到专门化并且不知道FSRVertex
的大小不再是问题。这有点傻,但它可以做你想做的,并且没有运行时开销:
class FSRVertex; // fwd
template <class FSRVertex_Forward = FSRVertex> // make fwd the default type
class FSREdge_
public:
char fC;
FSRVertex_Forward fTarget;
FSREdge_(char c, FSRVertex_Forward target)
:fC(c), fTarget(target)
FSREdge_(const FSREdge_ &other) // std::map requires copy ctor
:fC(other.fC), fTarget(other.fTarget)
FSREdge_() // std::map requires default ctor
;
typedef FSREdge_<> FSREdge; // so that you don't have to carry the brackets everywhere
class FSRVertex
public:
std::map<char, FSREdge> fOutEdges;
FSRVertex()
:fOutEdges()
;
您可以在ideone 上看到这项工作。
【讨论】:
【参考方案3】:此错误表示前向声明不充分,您使用该类型的方式。
你无法修复它。
【讨论】:
无法修复是什么意思? @NeilKirk:前向声明不能用于必须知道大小的类型。前向声明无法修复。 @Neil 好吧,至少你可以高枕无忧了,因为其他三个人也无法理解这种基本的英语。 @NeilKirk:您无法进行前向声明。我不知道如何让你更清楚。 您对这个问题的理解太过分了。他想要一些变通办法,我给了一些。以上是关于使用前向声明时如何修复“字段类型不完整”错误的主要内容,如果未能解决你的问题,请参考以下文章