【问题标题】:Move constructors and the Strong Exception Guarantee移动构造函数和强异常保证
【发布时间】: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的问题是你修改了原件。因此,在移动容器并抛出第三个元素时,您不能保证前两个元素可以恢复到原始状态。

标签: c++ exception c++11


【解决方案1】:

我没有检查具体的实现,但总体思路是,如果移动构造函数可以抛出,向量将不得不复制元素。这样就可以在发生异常时回滚。

甚至在<utility> 中定义了一个辅助函数move_if_noexcept 来帮助它决定要做什么。

【讨论】:

  • 有趣。我要检查我感兴趣的库中是否存在这个move_if_noexcept(顺便说一句,你有错字)助手。
  • @Alexander - MSVC10 没有机会完全符合,因为右值规则在发布后发生了变化。
猜你喜欢
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 2014-01-05
  • 2011-03-11
  • 2010-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多