C++标准保证std::swap
不会抛出异常。但是,如果要交换的对象在交换期间引发异常怎么办?接下来,调用方应如何查找已发生的异常?呼叫者应采取哪些措施?
PS:构造函数引发异常是很常见的。
struct A
{
A(const A&)
{
throw 1;
}
A& operator =(const A&)
{
throw 2;
return *this;
}
};
int main()
{
A a1, a2;
std::swap(a1, a2); // An exception happened, but the caller doesn't know.
// How to do here ???
}
C++标准保证 std::swap 不会引发异常。
不,它没有。请参阅 20.2.2 或参考。对于这两种std::swap
重载,有两种例外规范:
template<class T> void swap(T& a, T& b)
noexcept(noexcept(
std::is_nothrow_move_constructible<T>::value &&
std::is_nothrow_move_assignable<T>::value
))
template<class T, size_t N>
void swap(T (&a)[N], T (&b)[N])
noexcept(noexcept(swap(*a, *b)))
当这些条件不满足时,std::swap
可以投掷,你可以接住它。
对于您提供的类,谓词 std::is_nothrow_move_constructible
和 std::is_nothrow_move_assignable
为 false,因此实例化std::swap<A>
没有不抛出保证。从此交换中捕获异常是完全合法的。
该标准通常不保证交换不会抛出。
从 20.2.2/1:
模板无效交换(T&a,T&b)noexcept(见下文);
备注:noexcept 中的表达式等效于:
is_nothrow_move_constructible<T>::value && is_nothrow_move_assignable<T>::value