简体   繁体   English

为什么仅保证这些C ++标准库容器允许不完整的类型?

[英]Why are only these C++ standard library containers guaranteed to allow incomplete types?

It's a well-known fact that the C++ standard library containers, in general, cannot be instantiated with incomplete types. 众所周知,C ++标准库容器通常不能使用不完整的类型实例化。 The result of doing so is UB, although in practice a given implementation will either accept the code without issues or issue a compilation error. 这样做的结果是UB,尽管在实践中给定的实现将接受没有问题的代码或发出编译错误。 Discussion about this restriction can be found here: Why C++ containers don't allow incomplete types? 关于此限制的讨论可以在这里找到: 为什么C ++容器不允许不完整的类型?

However, in C++17, there are three containers that explicitly allow incomplete types: std::forward_list (26.3.9.1/4), std::list (26.3.10.1/4), and std::vector (26.3.11.1/4). 但是,在C ++ 17中,有三个容器明确允许不完整的类型: std::forward_list (26.3.9.1/4)、 std::list (26.3.10.1/4)和std::vector (26.3)。 11.1 / 4)。

This is the result of N4510 . 这是N4510的结果。 The paper notes that "based on the discussion on the Issaquah meeting" the decision was made to, at least at first, limit such support to those three containers. 该文件指出,“根据伊萨夸会议的讨论”,决定至少在最初将这种支持限制在这三个集装箱内。 But why? 但为什么?

Because we know how to implement those containers to deal with incomplete types, without breaking the ABI. 因为我们知道如何实现这些容器以处理不完整的类型,而又不会破坏ABI。

std::array , on the other hand, needs to know how big an element is (for example). 另一方面, std::array需要知道一个元素有多大(例如)。

But why? 但为什么?

The reason incomplete types weren't allowed in the standard containers was that some containers can work with them, but some don't. 标准容器中不允许使用不完整类型的原因是某些容器可以使用它们,而有些容器则不能。 They didn't want to think too much about this issue at the time and made a blanket prohibition of incomplete types in all standard containers. 他们当时不想对此问题考虑太多,因此全面禁止所有标准容器中的不完整类型。

Matt Austern documented that in his great article "The Standard Librarian: Containers of Incomplete Types", which is no longer available, but there are still quotes from it in Boost Containers of Incomplete Types . 马特·奥斯汀(Matt Austern)在他的精彩文章“标准图书馆员:不完整类型的容器”中指出,该文章不再可用,但是在不完整类型的Boost容器中仍然引用了它。

This C++17 change does justice by undoing the harm inflicted by that blanket prohibition. C ++ 17的这一更改通过消除该全面禁止所造成的伤害来实现公正。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM