为什么 C++ 容器不允许不完整的类型?

2021-12-13 00:00:00 templates c++ stl incomplete-type

为什么 C++ 不允许实例化不完整类型的容器?

Why doesn't C++ allow containers of incomplete types to be instantiated?

当然可能编写没有此限制的容器 -- boost::container 完全有能力做到这一点.据我所知,它似乎没有提供任何性能或其他类型的增益,但标准声明它是未定义的行为.

It's certainly possible to write containers that don't have this restriction -- boost::container is completely capable of doing this. As far as I can see, it doesn't seem to give any performance or other type of gain, and yet the standard declares it to be undefined behavior.

例如,它确实阻止构建递归数据结构.

It does prevent recursive data structures from being built, for example.

为什么 C++ 标准会强加这种任意限制?尽可能允许不完整类型作为模板参数有什么缺点?

Why then does the C++ standard impose this arbitrary restriction? What would have been the downside of allowing incomplete types as template parameters wherever possible?

推荐答案

C++ 标准化委员会图书馆工作组主席 Matt Austern 在他的 博士.多布的文章按历史原因:

Matt Austern, the chair of the C++ standardization committee's library working group, explained this decision of the committee in his Dr. Dobb's article by historical reasons:

通过更多的测试,我们发现即使是 [简单] 示例也不适用于每个 STL 实现.最后,这一切似乎太模糊,太难理解了;标准化委员会认为除了说 STL 容器不应该处理不完整类型之外别无选择.为了更好地衡量,我们也将该禁令应用于标准库的其余部分.

We discovered, with more testing, that even the [simple] example didn't work with every STL implementation. In the end, it all seemed too murky and too poorly understood; the standardization committee didn't think there was any choice except to say that STL containers aren't supposed to work with incomplete types. For good measure, we applied that prohibition to the rest of the standard library too.

我对此的理解是,委员会不希望通过要求库的现有实现追溯支持不完整类型来使其无效.

My understanding of this is that the committee did not want to invalidate existing implementations of the library by requiring them to support incomplete types retroactively.

在同一篇文章中,他承认

In the same article he concedes that

在 C++ 的未来修订版中,放宽对实例化具有不完整类型的标准库模板的限制可能是有意义的.

In a future revision of C++, it might make sense to relax the restriction on instantiating standard library templates with incomplete types.

鉴于这篇文章可以追溯到 2002 年,并且禁令在当前标准中仍然存在,我认为 boost 设计者决定不等待未来并构建自己的允许不完整类型的容器是完全合理的.

Given that the article dates back to 2002, and the prohibition remains in place in the current standard, I think that the decision of the boost designers not to wait for the future and build their own containers that allow incomplete types was fully justified.

有关使用 C++ 允许的不完整类型的信息,请参阅此答案标准 C++ 库中某些容器的 17 个标准.

See this answer for information on using incomplete types allowed by C++17 standard for some containers in the Standard C++ Library.

相关文章