【发布时间】:2011-05-15 21:37:27
【问题描述】:
只是一个简短的问题,我找不到很好的参考,尤其是关于未来 C++0x 标准的当前实现。
由于move constructors can throw,意味着一些标准库函数不能提供强异常保证(例如vector<T>::resize())。
有人提议 1) 使所有标准库移动构造函数“不抛出”,以及 2) 对用户代码添加编译时检查以确保例如。 std::pair<std::string, MyType> 定义了一个 nothrow move 构造函数或根本没有 move 构造函数。
这个提议发生了什么事(尤其是关于this question)?最终草案中的问题是如何“解决”的?
最重要的是,当我使用最新的 GCC 或 MSVC 10 时,这对我意味着什么?标准库的那些实现是否提供了强异常保证,例如。 std::vector<MyTypeWithAThrowingMoveConstructor>::resize()?
编辑:我没有看到明显相关的this question。如果对我的问题重复这一事实达成共识,请关闭它。但是,我真的对实施的内容感兴趣,而不是讨论过的内容。
【问题讨论】:
-
+1 非常好奇的问题
-
他们是否提供过强有力的异常保证?我的意思是,您的复制构造函数总是可以抛出,所以...
-
@Xeo:是的,他们做到了。回滚调整大小操作很容易,因为旧缓冲区在所有副本都成功后被销毁。使用 nothrow move 构造函数,您也可以通过将元素移回旧缓冲区来回滚。使用 throwing move 构造函数,Bad Things 可能会发生。在这里,我们清楚地看到缺少 strong
noexcept关键字。 -
@Xeo:很容易在copy上提供强大的异常保证。如果任何副本失败,则您将恢复为原始副本(未更改)。 move的问题是你修改了原件。因此,在移动容器并抛出第三个元素时,您不能保证前两个元素可以恢复到原始状态。