为什么' boost::container::flat_set '不是' nothrow_move_constru
Why is `boost::container::flat_set` not `nothrow_move_constructible`?
我正在编写一些代码,该代码具有一个通用容器,要求元素为nothrow_move_constructible
。
我决定添加一个static_assert
来强制执行,以防万一。
令我惊讶的是,我现在不能编译时使用boost::container::flat_set
。
我以为这只是一个疏忽,我需要一个最近的增强版本,但似乎实际上他们故意使它不安全移动:
查看文档:
http://www.boost.org/doc/libs/1_61_0/doc/html/boost/container/flat_set.html您可以看到他们确实更新了它以使用r值引用并将swap
标记为noexcept
,但他们选择不使移动向量noexcept
。看起来move赋值是有条件的noexcept
。该条件似乎在某种程度上取决于值类型和分配器。
nothrow move不可构造的基本原理是什么?这只是一个疏忽吗?
如果容器中的对象不是nothrow_move_constructible
,那么在某些情况下(通常涉及分配器),将一个容器的整个集合重新定位到另一个容器是非常危险的。如果两个容器不是用相同的分配器构造的,那么将内存从一个容器移动到另一个容器是不安全的(想想来自两个不同内存领域的两个容器)。
深入到当前源,合约和实现都有问题:
//! <b>Effects</b>: Move constructs a flat_map.
//! Constructs *this using x's resources.
flat_map(BOOST_RV_REF(flat_map) x)
: m_flat_tree(boost::move(x.m_flat_tree))
{ ... }
所以你当前对nothrow
的期望是正确的。但是他们这样做可能是不对的。
我只能猜测他们担心将来不得不重新访问这个协议,并且不想以后不得不削弱nothrow
合约。
相关文章:
- new(std::nothrow) int[n] 抛出异常
- 使用未声明的标识符"nothrow";你是说"扔"吗?记忆
- std::make_shared 和 std::make_unique 有"nothrow"版本吗?
- Linux g++ new (std::nothrow) 确实有效
- 模板通过一个专门化同时接受throw和nothrow
- 处理"Thrown exception type is not nothrow copy constructible"警告
- 为什么std::nothrow在gcc(4.9)中没有按预期工作
- 运算符++()nothrow不编译
- 如何为析构函数指定nothrow异常说明符
- 默认析构函数nothrow
- new(std::nothrow)而不是new和错误处理
- 将函数声明为 __attribute__(nothrow) 和 'throw()' 有什么区别
- throw()(即__declspec(nothrow))在视觉C++中是否带来了真正的好处
- 向量、移动语义、Nothrow 和 G++ 4.7
- 如何使用new(std::nothrow)使构造函数失败
- 我似乎无法将MS泄漏检测器用于新表达式“new(std::nothrow)”.是这样吗
- 为什么新的std::nothrow版本没有被广泛使用
- 带nothrow选项的Operator new仍然会抛出异常
- Std::string not nothrow move可赋值或可比较
- 在extern C中使用_attribute__ ((nothrow))有意义吗?