【问题标题】:stl container of references C++11stl 引用容器 C++11
【发布时间】:2016-01-13 16:02:25
【问题描述】:

我知道这个问题被问了一百万次。大多数答案只是说对象应该是 CopyAssignable 和 CopyConstructible。但是documentation 明确表示这是规则(直到 C++11)!但它仍然不起作用。为什么?

【问题讨论】:

    标签: c++


    【解决方案1】:

    是的,现在要求不那么严格了。但是,在您引用的部分正下方,链接文档明确指出

    对元素的要求取决于对容器执行的实际操作。一般要求元素类型是完整类型,满足Erasable的要求,但很多成员函数的要求更严格。 (C++11 起)

    引用不符合 Erasable 的要求,因此它们仍然无法工作。

    【讨论】:

      【解决方案2】:

      这些规则适用于 C++11。在 C++11 中要求元素类型是一个完整的类型并且满足 Erasable 的要求,在这种情况下引用不是。

      但是,您可以使用 std::reference_wrapper 包装您的引用并将它们存储在向量中。

      std::vector<std::reference_wrapper<T>> vector_of_references;
      

      【讨论】:

      • 是的,我知道std::reference_wrapper。而且我仍然不确定规则。您是说文档中有错误吗?
      • @101010 这不是额外要求
      • @101010 新要求没有 c++11 之前那么严格。一个类型不再需要是 CopyAssignable 和 CopyConstructible 才能在向量中使用,只要它是可擦除的。
      • 您可以编辑您的答案,说明引用不符合新限制 (Erasable)。
      【解决方案3】:

      C++11 放宽了容器要求,因此可以在容器中使用非 CopyConstructible 类型,只要避免需要复制元素的操作即可。

      但这并不意味着允许引用,仅仅因为放宽了一个规则并不意味着绝对可以将任何类型放入容器中。

      作为 cppreference 页面,您为 C++11 引用了 says

      对元素的要求取决于对容器执行的实际操作。一般要求元素类型是完整类型,满足Erasable的要求,但很多成员函数要求更严格。

      Erasable 要求这是有效的:

      allocator_traits<A>::destroy(m, p)
      

      17.6.3.5 [allocator.requirements] 中的Allocator 要求说分配器处理任何非常量对象类型,并且引用不是对象类型,因此您不能分配或取消分配引用,因此您不能将它们放入容器中。

      【讨论】:

      【解决方案4】:

      § 23.2.1 [container.requirements.general] ¶ 1 of N4140 说(强调我的):

      容器是存储其他对象的对象。它们通过构造函数、析构函数、插入和擦除操作来控制这些对象的分配和释放。

      但是引用不是对象,所以不能将它放入标准库容器中。

      【讨论】:

        猜你喜欢
        • 2014-07-19
        • 2012-10-07
        • 2013-07-02
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        • 2011-02-07
        • 2012-02-08
        相关资源
        最近更新 更多