What if an object passed into std::swap throws an exception during swapping?

痞子三分冷 提交于 2021-02-08 14:14:44

问题


The C++ standard guarantees that std::swap will throw no exception. However, what if an object to swap throws an exception during swapping? Next, how should the caller find an exception has happened? and what measures should the caller take?

PS: It is very common that a constructor throws an exception.

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 ???
}

回答1:


The C++ standard guarantees that std::swap will throw no exception.

No, it doesn't. See 20.2.2 or the reference. There are two noexcept specifications for the two std::swap overloads:

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)))

When these conditions aren't satisfied, std::swap can throw and you can catch it.


In case of the class you have presented, the predicates std::is_nothrow_move_constructible and std::is_nothrow_move_assignable are false, so the instantiation std::swap<A> doesn't have the no-throw guarantee. It's perfectly legal to catch exceptions from this swap.




回答2:


The standard does not generally guarantee that swap doesn't throw.

From 20.2.2/1:

template void swap(T& a, T& b) noexcept(see below);

Remark: The expression inside noexcept is equivalent to:

 is_nothrow_move_constructible<T>::value &&
 is_nothrow_move_assignable<T>::value


来源:https://stackoverflow.com/questions/14601469/what-if-an-object-passed-into-stdswap-throws-an-exception-during-swapping

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!