What if the object passed to std :: swap throws an exception during replacement?

The C ++ standard ensures that std::swap does not throw an exception. However, what if the object for swap throws an exception during replacement? Then, how should the caller call? and what measures should the caller take?

PS: Very often, the 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 ??? } 
+6
source share
2 answers

The C ++ standard ensures that std :: swap will not exclude.

No, it is not. See 20.2.2 or link . For two std::swap overloads, there are two noexcept specifications:

 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 are not met, std::swap can throw, and you can catch it.


In the case of the class you presented, the predicates std::is_nothrow_move_constructible and std::is_nothrow_move_assignable are false, so there is no guarantee of no throw in the instance of std::swap<A> . It is perfectly legal to catch exceptions to this swap.

+16
source

The standard usually does not guarantee that swap does not throw.

From 20.2.2 / 1:

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

Note: the expression inside noexcept is equivalent to:

  is_nothrow_move_constructible<T>::value && is_nothrow_move_assignable<T>::value 
+10
source

All Articles