我很好奇是否可以创建两个类,每个类都包含std::vector另一个类.我的第一个猜测是,这是不可能的,因为std::vector需要一个完整的类型,而不仅仅是一个前向声明.
#include <vector>
class B;
class A { std::vector<B> b; };
class B { std::vector<A> a; };
Run Code Online (Sandbox Code Playgroud)
我认为声明std::vector<B>会立即导致失败,因为B此时类型不完整.但是,这在gcc和clang下成功编译,没有任何警告.为什么这不会导致错误?
TC评论说这实际上是未定义的行为,正在对标准的变更请求中解决.被违反的规则显然是[res.on.functions] 2.5:
特别是,在下列情况下,效果尚未明确:[...]
- 如果在实例化模板组件时将不完整类型(3.9)用作模板参数,除非特别允许该组件.
无论如何它的工作原因(以及它可以标准化的原因)是双重的:
您的程序只包含类型定义; 没有创建对象,没有调用函数,也没有生成代码.如果我们通过消除B的定义(它不需要)来简化它,然后尝试创建一个实例A,它就会失败:
class B;
class A { std::vector<B> b; };
A a; // error: ctor and dtor undefined for incomplete type B.
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,失败也很简单
std::vector<B> b;
Run Code Online (Sandbox Code Playgroud)
两种情况下的原因是编译器必须生成代码,而不仅仅是语法相关的纯类型声明.
在其他情况下,矢量类型的使用也可以:
typedef std::vector<B> BVec;
Run Code Online (Sandbox Code Playgroud)A可以定义类,因为正如Nikolay在他的回答中正确地说的那样,其成员std::vector<B>的大小和因此的大小不依赖于定义(因为向量包含指向元素数组的指针,而不是数组正确).AbB
| 归档时间: |
|
| 查看次数: |
336 次 |
| 最近记录: |