据说复制和交换习语提供了强有力的异常保证。但是在C ++ 11中,std :: swap使用移动操作。
请考虑以下代码:
class MyClass
{
AClass x;
CanThrowIfMoved throwingObject;
MyClass(MyClass&& other) noexcept
x(std::move(other.x)),
throwingObject(std::move(other.throwingObject))
{ }
friend void swap(MyClass& first, MyClass& second) noexcept
{
using std::swap;
swap(first.x, other.x);
swap(first.throwingObject, other.throwingObject);
}
MyClass& operator=(MyClass other) noexcept
{
swap(*this, other);
return *this;
}
};
如果在交换期间抛出throwingObject
,则强烈的异常保证会被破坏。
noexcept
个关键字在编译期间不执行任何操作。 throwingObject
仍然可以投掷,唯一的区别是该计划会暴力terminate
。我不认为发生异常时崩溃整个应用程序会被视为一个强大的异常保证。
这是否意味着copy-and-swap不再强制执行C ++ 11中的强异常保证?
类似问题
This question类似,但它的目标是使用标准库。我对此问题对于复制和交换习惯用语的强大异常保证意味着什么感兴趣。
This question讨论了如何在复制和交换习惯用法中使用noexcept
,但只讨论了副本。不是交换,这就是问题所在。
答案 0 :(得分:2)
不是直接在swap
成员方法中调用swap
,而是使用辅助函数模板,该模板在编译时检查noexcept
保证:
friend void swap(MyClass& first, MyClass& second) noexcept
{
util::swap_noexcept(first.x, other.x);
util::swap_noexcept(first.throwingObject, other.throwingObject);
}
namespace util
{
template <typename ...Args>
void swap_noexcept(Args&&... args) noexcept
{
using std::swap;
static_assert(noexcept(swap(std::forward<Args>(args)...)), "requires noexcept");
swap(std::forward<Args>(args)...);
}
}