为什么 C++不允许实例化不完整类型的容器?
编写没有这个限制的容器当然是可能的 - boost :: container完全能够做到这一点.据我所知,它似乎没有给出任何性能或其他类型的增益,但标准声明它是未定义的行为.
例如,它确实阻止了构建递归数据结构.
为什么C++标准会强加这种任意限制呢?尽可能允许不完整类型作为模板参数的缺点是什么?
出现以下问题:
c ++标准似乎在说,这std::vector
需要一个完整的类型才能起作用。(请参阅https://en.cppreference.com/w/cpp/container/vector)那么,为什么下面的代码仍然可以编译?
#include <vector>
struct parent;
struct child
{
std::vector<parent> parents; //parent is incomplete here!
};
struct parent
{
std::vector<child> children;
};
Run Code Online (Sandbox Code Playgroud)
这似乎违反直觉。如果std::vector
需要完整的类型,则std::vector<parent>
不应编译,因为在的类定义中仅知道其前向声明child
。
std::vector
了吗,不需要完整的类型?编辑
c ++ 11和c ++ 17之间似乎有所不同。我想了解c ++ 11版本。
请考虑以下代码段,其中第一行仅用作前向声明
class A;
Run Code Online (Sandbox Code Playgroud)
然后定义新类
class B
{
vector<A> Av; //line 1
map<int, A> Am; //line 2
pair<int, A> Ap; //line 3
};
Run Code Online (Sandbox Code Playgroud)
第1行和第2行似乎没有前向声明(这可能告诉我那些容器使用指针类型的实现),其中第3行似乎不在VS2012上编译.
我的问题是标准或特定于我正在使用的编译器所规定的行为?
谢谢
假设我有一些不完整的类型
// in foo.hh
struct Hidden;
Run Code Online (Sandbox Code Playgroud)
我想用作 a 的元素类型std::vector
。使用union
I 可以“推迟”对构造函数和析构函数的调用以std::vector
实现联合构造函数/析构函数。
// in foo.hh
struct Public {
union Defer {
std::vector<Hidden> v;
Defer();
// add copy/move constructor if needed
~Defer();
} d;
};
Run Code Online (Sandbox Code Playgroud)
现在我只能Public
通过包含foo.hh
和链接实现Public::Defer::Defer()
和的文件来使用Public::Defer::~Defer()
。只有那些需要访问Hidden
.
这是合法的 C++ 吗?如果有,从什么时候开始?
背景:我在回答另一个问题时提出的问题。