SGSharedPtr: more efficient copy and move assignment operators

The copy-and-swap idiom is certainly very cute, but often causes
unnecessary copies. My commit fedafb9352
did exactly that, unfortunately.

Restore the exact same code for the copy-assignment operator as before
commit fedafb935, and add a more efficient implementation for the
move-assignment operator.

As explained by Howard Hinnant in [1] and [2], if some particular piece
of code really needs a strong exception safety guarantee, one can easily
add a specific method for that; this is not a valid reason to make the
code slower for all other places that have no use for such a guarantee!

[1] http://www.slideshare.net/ripplelabs/howard-hinnant-accu2014
[2] https://stackoverflow.com/a/9322542/4756009
This commit is contained in:
Florent Rougon
2017-11-12 23:42:58 +01:00
parent bd87d3963a
commit bc3404fcbe

View File

@@ -67,10 +67,19 @@ public:
~SGSharedPtr(void)
{ reset(); }
// This handles copy assignment using the copy-and-swap idiom, and also move
// assignment thanks to the move construtor.
SGSharedPtr& operator=(SGSharedPtr p)
{ swap(p); return *this; }
SGSharedPtr& operator=(const SGSharedPtr& p)
{ reset(p.get()); return *this; }
SGSharedPtr& operator=(SGSharedPtr&& p)
{ // Whether self-move is to be supported at all is controversial, let's
// take the conservative approach for now
if (this != &p) {
swap(p);
p.reset();
}
return *this;
}
template<typename U>
SGSharedPtr& operator=(const SGSharedPtr<U>& p)
{ reset(p.get()); return *this; }