如果传递到 std::swap 的对象在交换过程中引发异常怎么办?



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_constructiblestd::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

最新更新