C ++ 17添加了std::uninitialized_move
,但是没有std::uninitialized_move_if_noexcept
在内部使用std::move_if_noexcept
。我认为这会很有用,因为从现在开始,如果我们要重新分配,我们仍然需要编写如下内容:
if constexpr (!std::is_nothrow_move_constructible_v<value_type>
&& std::is_copy_constructible_v<value_type>)
std::uninitialized_copy(...);
else
std::uninitialized_move(...);
在C ++ 17中没有引入std::uninitialized_move_if_noexcept
的原因有哪些?
答案 0 :(得分:8)
"Extending memory management tools"上有关open-std.org的一篇论文中有一个关于uninitialized_move
的部分,讨论了此问题。
对于
uninitialized_move
的异常处理引起了一些关注。如果移动构造函数抛出,则源对象可能已被不可修复地损坏。由于无法解决此问题,因此我们实现了自然和预期的语义,即销毁目标缓冲区中所有完全构造的对象并传播异常。这与uninitialized_copy
的行为尽可能接近。 可以考虑使用其他算法uninitialized_move_if_noexcept
作为解决此问题的方法。发现这样的算法已经使用move_if_noexcept
迭代器在libstdc ++中实现。 鉴于当前没有基于范围的move_if_noexcept
算法,此处不考虑这种解决方案。显然,这种功能很容易实现。