为了账号安全,请及时绑定邮箱和手机立即绑定

可以使用不完整的类型实例化标准容器模板吗?

可以使用不完整的类型实例化标准容器模板吗?

C++
暮色呼如 2019-11-20 14:08:25
有时实例化具有不完整类型的标准容器以获得递归结构很有用:struct multi_tree_node { // Does work in most implementations    std::vector< multi_tree_node > child;};struct trie_node { // Does not work in most implementations    std::map< char, trie_node > next;};因为容器没有类型value_type或成员函数来value_type按值传递或返回任何对象的成员,所以这种方法趋于起作用。标准似乎对不完整的模板参数没有说太多,但是在C ++ 11§17.6.4.8[lib.res.on.functions]中有一点,“其他函数的要求”:特别是,在以下情况下,效果是不确定的:…如果在实例化模板组件时将不完整类型(3.9)用作模板参数,除非该组件特别允许。即使实例不在块范围内,这也使上述构造非法吗?这是否属于“对用于实例化标准库模板组件的类型的操作”(也是17.6.4.8)?还是在所有特别要求的实例化成功后,禁止库实现产生可能因不完整类型而失败的模板实例化?编辑:由于只有函数可以调用和实例化其他函数,所以将“对类型的操作…”限制为块范围内的那些似乎会使成员函数的内容比签名和成员类定义的内容严格。毕竟,在类型完成之前,对a 做任何事情当然是没有意义的multi_tree_node。甚至扩展到std::unique_ptr,即使在块范围中使用,它也显式支持不完整的类型参数。编辑2:为我服务,不用打扰测试trie_node示例-甚至我以前都尝试过。它与@Ise链接的文章中的损坏示例相同。但是,尽管这篇文章似乎认为“什么都行不通”是理所当然的,但对我而言,解决方案似乎很简单- std::map内部tree_node类应该是非成员模板,而不是成员非模板类。无论如何,那篇文章很好地确立了设计意图,所以我猜我对“功能要求”子标题下的看法只是这样。
查看完整描述

2 回答

?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

就我个人而言,我觉得在17.6.4.8/2中实例化的措辞有点含糊,但是根据 本文,标准的意图似乎不允许使用标准容器的递归数据类型。


在相关说明中,VC2005 class C { std::deque< C > x; };在编译时会 发出的错误 class C { std::vector< C > x; };。

但是,据我了解,此限制仅是为了扩展实现标准容器的自由度。因此,正如Kerrek SB所提到的,可以有一些容器允许递归数据结构,而 Boost.Container 似乎提供了这种功能。


查看完整回答
反对 回复 2019-11-20
?
小唯快跑啊

TA贡献1863条经验 获得超2个赞

这是我的一种解释尝试:


该标准只是说您不必执行此操作,即使任何给定的具体实现都可能在支持这种构造上没有问题。但是,例如,假设有人想编写一个“小向量”优化方法,即向量始终包含五个元素的空间。您马上就会遇到麻烦,因为您将拥有一个自引用类型。即使向量根据值类型的大小采用某种静态分支,这也将是一个问题。


因此,为了不使实现不包含此类构造,该标准仅声明您必须仅使用完整类型。换句话说,大多数容器仅包含对值类型的引用或指针这一事实是实现细节,而不是标准要求。


只是为了澄清这一点:如果定义自己的类模板,则完全有可能以明确支持不完整类型的方式进行设计。该标准的一个示例是std::unique_ptr,它对不完整的类型参数T[](甚至void)非常满意。


查看完整回答
反对 回复 2019-11-20
  • 2 回答
  • 0 关注
  • 480 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信