Exception 在C+中,复制和交换是否仍然提供强大的异常保证+;11?
据说复制和交换习惯用法提供了强有力的异常保证。但是在C++11中,std::swap使用移动操作 考虑以下代码:Exception 在C+中,复制和交换是否仍然提供强大的异常保证+;11?,exception,c++11,copy-and-swap,Exception,C++11,Copy And Swap,据说复制和交换习惯用法提供了强有力的异常保证。但是在C++11中,std::swap使用移动操作 考虑以下代码: class MyClass { AClass x; CanThrowIfMoved throwingObject; MyClass(MyClass&& other) noexcept x(std::move(other.x)), throwingObject(std::move(other.throwingOb
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
仍然可以抛出,唯一的区别是程序将剧烈地终止
。我不认为在发生异常时使整个应用程序崩溃是一种强有力的异常保证
这是否意味着复制和交换不再强制C++11中的强异常保证
类似问题 与之类似,但它的目标是使用标准库。我感兴趣的是这个问题对于复制和交换习惯用法的强大异常保证意味着什么
讨论如何在复制和交换习惯用法中使用
noexcept
,但仅讨论复制。不是swap,这似乎就是问题所在。不要在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)...);
}
}
好友无效交换(MyClass&first,MyClass&second)无例外
{
util::swap_noexcept(first.x,other.x);
util::swap_noexcept(first.throwingObject,other.throwingObject);
}
命名空间util
{
模板
无效交换\u无例外(Args&…Args)无例外
{
使用std::swap;
静态断言(noexcept(swap(std::forward(args)…),“需要noexcept”);
交换(标准:转发(参数)…);
}
}
复制交换的主要先决条件是非抛出的交换
函数,因此您的问题不在于复制交换。@chris这个问题背后的主要观点是,考虑到您依赖其他类的移动构造函数,是否可能提供非抛出的交换函数(其定义将来可能会更改)。看起来这会起作用。这是否意味着这些静态断言真的应该在每个交换函数中使用?成员的类型和类定义总是可以更改以删除其noexcept
,因此手动检查并期望它们保持这种状态似乎不安全。@Aberrant:helper函数swap_noexcept
只需编写一次,因此,静态断言
。如果从交换
函数中删除noexcept
,编译失败是好的,否则代码将在运行时中断。对不起,我认为我的措辞错误。我的问题是,我认为您必须始终使用该函数对吗静态断言在某种程度上真的能够给予有力的保证吗?