在即将发布的C++0x标准中,如果在移动构造函数期间抛出异常会发生什么?
原始对象会保留吗?还是原始对象和移动到的对象都处于未定义状态?语言提供了哪些保证?
原始对象会保留吗?还是原始对象和移动到的对象都处于未定义状态?语言提供了哪些保证?
我相信标准委员会最初尝试使移动构造函数不能抛出异常,但至少从今天的情况来看,他们发现试图强制执行这一点有太多的缺陷。
提案N3050,“允许移动构造函数抛出异常(修订1版)”已纳入草案标准。本质上,该提案增加了移动构造函数抛出异常的能力,但禁止“抛出式移动”用于某些需要强烈的异常安全保证的操作(如果没有非抛出式移动可用,则库将回退到复制对象)。
如果将移动构造函数标记为不抛出 (noexcept
) 且抛出异常,将调用 std::terminate()。
阅读David Abrahams的博客文章也可能很值得,该文章讨论了N3050旨在解决的问题:
swap
不能抛出异常的论证。作为基本情况,重新分配和复制原语永远不会抛出异常。作为归纳步骤,具有一些数据成员的对象的移动构造函数可以在不抛出异常的情况下移动这些数据成员(归纳假设!),因此可以在不抛出异常的情况下移动自身。然而,独立地,我仍然想知道您问题的正确答案是什么。 - templatetypedef