fill insert() - 复制构造函数和复制赋值noexcept status?

时间:2015-08-24 10:25:18

标签: c++ stl insert copy-constructor copy-assignment

  1. STL容器元素是否需要noexcept复制构造函数和复制赋值运算符?如果可能,请提供参考。
  2. 如果不是,在多插入期间发生异常时STL容器的状态是什么,例如在填充插入期间。
  3. 尝试编写允许拦截/否决修改的通用包装时会出现问题。我可以提出的任何实现都可能会改变底层容器的语义,除非专门针对每个容器类型(这不是一个真正的选项)。

    例如,std::vector有一个填充插入

    void insert (iterator position, size_type n, const value_type& val);
    

    这需要value_type同时为 CopyInsertable 以及 CopyAssignable 。请注意,要求值类型为 DefaultConstructible

    编辑3 Stroustrup他自己(第956页的表格)表示多元素插入应该具有强保证对于所有向量,双端队列,列表和地图。意味着完整的标准库操作要么原子成功要么失败。

    编辑4 但是,保证仅适用于相关操作(在本例中为复制构造函数)本身不会抛出异常,这正是我的问题。

    据我了解,这留下了两种基本的实现方法:

    1. 为新元素创建虚拟条目并复制分配val。这只有在可以通过复制容器中的现有元素或value_type DefaultConstructible (这不是必需的)创建虚拟元素时才有效。
    2. 将构造元素一个接一个地直接复制到容器中各自的位置。这似乎或多或少是规范的实施。
    3. 编辑2 :我不会调用此未定义的行为,因为该术语似乎会让人们认为未定义为语言运行时/标准

      两个实现似乎都将容器内容保留为未知内容(即不清楚容器在异常后保留哪些元素)当复制构造函数或复制赋值运算符引发时例外

      编辑1 :请注意,这并不意味着我认为C ++运行时存在不良行为,例如:内存泄漏或未定义的值。但是,它似乎或多或少未指定容器的内容是什么。特别是,容器的内容可以完全(尽管一直)改变。

      例如,考虑第三种(混合)方法:

      1. 创建模板对象n的{​​{1}}份副本列表。
      2. 将此列表中的元素复制分配到目标容器中。
      3. 不同之处在于复制构造函数引发异常时对容器的影响。在这种情况下,如果复制构造函数抛出(但在复制赋值运算符抛出时仍会导致未指定的内容),则容器的内容保持不变。当使用指针时(即不使用val时),可能会遗漏复制分配,只重新排列指针,使操作原子化。异常。

        关于容器元素的std::vector:对象是通过noexcept创建的,不是allocator_traits<value_type>::construct(ptr, args)而我也找不到容器元素大多数都有noexcept的要求复制构造函数/ copy-assigment运算符(例如noexceptstd::shared_ptr需要这个)。

        请注意,copy-construct和copy-assign的自动生成操作必须为std::unique_ptr,除非他们需要调用本身可能引发异常的操作。

        这让我很困惑,我确信我错过了一些东西,但我无法弄清楚可能证明我错了的标准部分。

0 个答案:

没有答案