【问题标题】:Has C++11 changed requirements for elements of STL containers, and how?C++11 是否改变了对 STL 容器元素的要求,以及如何改变?
【发布时间】:2012-11-14 16:46:41
【问题描述】:

最近我对std::unique_ptr is acceptable for elements of STL containers 的事实感到惊讶,因为我认为这些元素是提供以下功能所必需的(this page 也是如此):

  • 没有参数的公共默认构造函数
  • 公共复制构造函数
  • 公共复制赋值运算符函数
  • 公共析构函数

std::unique_ptr 不可复制以使其持有的指针归单个对象所有,这与上述要求相矛盾。

标准是否改变了要求?如果有,有哪些变化?也许可移动对象或可复制对象就足够了? 我已经在网上搜索了自 C++11 以来要求是否发生了变化,但我找不到任何对我有帮助的页面......

【问题讨论】:

  • 我相信 C++11 需要复制构造函数或移动构造函数(类似地,复制赋值或移动赋值)。
  • "C++11 是否改变了对 STL 容器元素的要求?" 是的,非常如此。您是否阅读过明显的地方,例如Wikipedia 问之前?
  • @ildjarn 好吧,我编辑了我的问题,以便清楚地表达我的意图。

标签: c++ stl c++11


【解决方案1】:

是的,标准库容器的要求发生了重大变化。很难提供一个完整的列表(有很多很多),但这里有一些重要的:

std::vector 通常只要求其成员为MoveConstructibleMoveAssignable。 std::vector 的许多成员函数提出了更严格的要求。 vector::push_back 需要移动 CopyConstructible(取决于您传递的是右值还是左值),但新的vector::emplace_back 只要求有一个接受给定参数的可访问构造函数(此外到基线要求)。显然,任何调用 vector 的复制构造函数/赋值的尝试都需要类型为 CopyConstructible(即:您不能复制 std::vector<unique_ptr>)。

同样,大多数其他容器都减少了对类型的限制。它们还具有emplace 成员函数,允许您就地构造成员,以及 l/rvalue 插入函数。这意味着您不必复制值;您可以将它们移入或就地建造。

没有一个构造函数或析构函数是要求公开的;所有的构建都是通过调用allocator_traits<Allocator>::construct 来进行的。因此,如果您提供分配器,您可以将构造函数/析构函数设为私有。好吧,当然,只要您的分配器类可以访问它们。

简而言之,要求不那么严格,但要复杂一些。如果您限制自己对容器执行某些操作,则可以避免很多事情。

【讨论】:

  • 当您需要了解具体操作的需求时,您指的是什么?任何阅读此页面的人都会受益。
  • @NicolBoras:哦,这需要阅读标准……我会抓住一个。谢谢!
  • vector::emplace_back 仍然要求元素是可移动/可复制的,因为它可能会增大矢量。
  • @Nevin:是的,更具体地说,因为不能静态消除emplace_back 可能会增大向量,即使容量足够,也认为有必要复制或移动元素.
  • @Nevin:正如我所说,“std::vector 的许多成员函数有更严格的要求。”然后列出了其中一些更严格的要求。所有这些要求都是除了移动要求。
猜你喜欢
  • 2011-09-25
  • 1970-01-01
  • 1970-01-01
  • 2011-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-01
相关资源
最近更新 更多