What if an object passed into std::swap throws an exception during swapping?
c++, c++11, exception, standards, swap
Solution
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.
Problem
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 ??? } ```