如果有可能创建两个类,每个都拥有另一个std :: vector,我很好奇.我的第一个猜测是,这是不可能的,因为std :: vector需要一个完整的类型,而不仅仅是一个前向声明.
#include <vector> class B; class A { std::vector<B> b; }; class B { std::vector<A> a; };
我会认为std :: vector< B>的声明会导致立即失败,因为此时B的类型不完整.但是,这个在gcc和clang下成功编译,没有任何警告.为什么不会造成错误?
T.C评论说,这实际上是在对标准的变更请求中正在解决的未定义的行为.违反的规则显然是[res.on.functions] 2.5:
原文链接:https://www.f2er.com/javaschema/281798.htmlIn particular,the effects are undefined in the following cases: […]
- if an incomplete type (3.9) is used as a template argument when instantiating a template component,unless specifically allowed for that component.
这样做的原因(以及可以标准化的原因)是双重的:
>程序只包含类型定义;没有创建对象,没有调用函数,不生成代码.如果我们通过消除B的定义(不需要)来简化它,然后尝试创建一个A的实例,它将失败:
class B; class A { std::vector<B> b; }; A a; // error: ctor and dtor undefined for incomplete type B.
如预期的那样,也是一个简单的失败
std::vector<B> b;
在这两种情况下,原因在于编译器必须生成代码,而不是仅仅是语法相关的类型声明.
使用向量类型也可以在其他上下文中使用:
typedef std::vector<B> BVec;
> A类可以被定义,因为Nikolay在他的答案中正确地说出了std :: vector< B>的大小,因此A的成员b的大小不依赖于B的定义(因为向量保持指向一个元素数组,而不是一个数组).