2011-05-15 73 views
15

只是一个很快的问题,在这个问题上我找不到一个很好的参考,尤其是关于未来C++ 0x标准的当前实现。移动构造函数和强烈的例外保证

由于move constructors can throw,这意味着一些标准库函数不能提供强有力的例外保证(例如vector<T>::resize())。有一个建议,1)使所有标准库移动构造函数“不抛出”,2)在用户代码上添加编译时检查以确保例如。 std::pair<std::string, MyType>定义了一个nothrow移动构造函数或根本没有移动构造函数。

这个建议怎么样(特别是关于this question)?这个问题在最终草案中如何“解决”?

最重要的是,当我使用最近的GCC或MSVC 10时,它对我意味着什么?这些标准库的实现是否在例如。 std::vector<MyTypeWithAThrowingMoveConstructor>::resize()

编辑:我没有看到this question这显然是相关的。如果对于我的问题是重复的事实达成共识,请关闭它。但是,我真的很感兴趣的是实施,而不是什么已经讨论

+0

+1非常好奇的问题 – sehe 2011-05-15 21:39:05

+0

他们曾经提供过强大的例外保证吗?我的意思是,你的拷贝构造函数总是可以抛出,所以... – Xeo 2011-05-15 21:45:37

+0

@Xeo:是的,他们做到了。因为在所有副本都成功之后旧缓冲区被破坏*,所以很容易回滚调整大小操作。用一个nothrow移动构造函数,你也可以通过将元素移回旧缓冲区来回滚。通过投掷移动构造函数,Bad Things可能会发生。在这里我们清楚地看到,缺少* strong *'noexcept'关键字。 – 2011-05-15 21:49:30

回答

4

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

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

+0

有趣。我要检查这个'move_if_noexcept'(btw你有一个拼写错误)助手是否存在于我感兴趣的库中。 – 2011-05-15 21:55:36

+0

MSVC10没有它。 – 2011-05-15 21:57:18

+2

@Alexander - 由于右值规则在发布后发生了更改,MSVC10没有机会完全符合规则。 – 2011-05-15 22:00:29