noexcept
复制构造函数和复制赋值运算符?如果可能,请提供参考。尝试编写允许拦截/否决修改的通用包装时会出现问题。我可以提出的任何实现都可能会改变底层容器的语义,除非专门针对每个容器类型(这不是一个真正的选项)。
例如,std::vector
有一个填充插入:
void insert (iterator position, size_type n, const value_type& val);
这需要value_type
同时为 CopyInsertable 以及 CopyAssignable 。请注意,不要求值类型为 DefaultConstructible 。
编辑3 Stroustrup他自己(第956页的表格)表示多元素插入应该具有强保证对于所有向量,双端队列,列表和地图。意味着完整的标准库操作要么原子成功要么失败。
编辑4 但是,保证仅适用于相关操作(在本例中为复制构造函数)本身不会抛出异常,这正是我的问题。
据我了解,这留下了两种基本的实现方法:
val
。这只有在可以通过复制容器中的现有元素或value_type
DefaultConstructible (这不是必需的)创建虚拟元素时才有效。编辑2 :我不会调用此未定义的行为,因为该术语似乎会让人们认为未定义为语言运行时/标准
两个实现似乎都将容器内容保留为未知内容(即不清楚容器在异常后保留哪些元素)当复制构造函数或复制赋值运算符引发时例外。
编辑1 :请注意,这并不意味着我认为C ++运行时存在不良行为,例如:内存泄漏或未定义的值。但是,它似乎或多或少未指定容器的内容是什么。特别是,容器的内容可以完全(尽管一直)改变。
例如,考虑第三种(混合)方法:
n
的{{1}}份副本列表。不同之处在于复制构造函数引发异常时对容器的影响。在这种情况下,如果复制构造函数抛出(但在复制赋值运算符抛出时仍会导致未指定的内容),则容器的内容保持不变。当使用指针时(即不使用val
时),可能会遗漏复制分配,只重新排列指针,使操作原子化。异常。
关于容器元素的std::vector
:对象是通过noexcept
创建的,不是allocator_traits<value_type>::construct(ptr, args)
而我也找不到容器元素大多数都有noexcept
的要求复制构造函数/ copy-assigment运算符(例如noexcept
和std::shared_ptr
需要这个)。
请注意,copy-construct和copy-assign的自动生成操作必须为std::unique_ptr
,除非他们需要调用本身可能引发异常的操作。
这让我很困惑,我确信我错过了一些东西,但我无法弄清楚可能证明我错了的标准部分。