Using security system 4 security levels :
- No throw
- Strong guarantee - the operation is completed or completely rolled back
- The main guarantee is that invariants are preserved, there are no resource leaks.
- No guarantee
The assignment operator generated by the compiler has a basic exception guarantee if each member of the object provides a basic exception guarantee or "better", and if the invariants of the objects have no dependencies between the members.
This has a no-throw guarantee if each member nomination also does not have a throw guarantee.
This rarely (if ever) has a strong guarantee, which you might call "exception unsafe."
Copy-to-copy idiom is popular because the no-throw swap entry is often lightweight, and designers should already provide a reliable exception guarantee. The result is operator= with a robust exception guarantee. (In the case of move it is pseudo-strong, since the input is often not a rollback, but it is an rvalue)
void swap( Foo& other ) noexcept; // implement this Foo& operator=( Foo const& f ) { Foo tmp(f); swap( tmp ); return *this; } Foo& operator=( Foo && f ) { Foo tmp(std::move(f)); swap( tmp ); return *this; }
If you also take a copy by value, you can sometimes update operator= to what you don't throw away (with one exception, perhaps in the argument construct).
Foo& operator=( Foo f ) noexcept { swap( f ); return *this; }
in some cases, some Foo constructors are noexcept , while others are not: by accepting a different byte value, we provide the best exception guarantee that we can end up with (since the argument = can sometimes be a direct build, either by elite, or a direct build through {} ) .
For a language (at least at this time) it is not practical to implement “copy swap” operator= with a strong guarantee for several reasons. First, C ++ works on “you pay only for what you use,” and “copying” can be more expensive than copying in order. Secondly, swap is not currently part of the main language (there are suggestions to add operator :=: and collapse it). Third, backward compatibility with previous versions of C ++ and C.