This can be seen as a follow up to e.g. Why shared pointer assignment does 'swap'?.
The question is about the Copy&Swap idiom used e.g. in boost.
I do understand that the benefit of Copy&Swap is to reuse existing code which avoids duplication and bugs. But there are 2 cases (actually 1 can be reduced to the other) where it is not optimal:
- The smart pointer instances are the same
- The contained pointer is the same
For shared_ptr
the ref counters are incremented atomically and for intrusive_ptr
(boost only) they may be. So there is a high cost for a copy.
This can be avoided, if the assignment was implemented like:
smart_ptr& operator=(const smart_ptr& other){
if(this->ptr_ == other.ptr_) return *this;
smart_ptr(other).swap(*this); // I assume I can simply do this here, right?
return *this;
}
smart_ptr& operator=(smart_ptr&& other){
smart_ptr(std::move(other)).swap(*this);
return *this;
}
Wouldn't this be the fastest and safest implementation or is there any issue I did not see?
If it is the fastest, why aren't boost or the stdlib using it?
To clarify on point 2. consider the following code:
smart_ptr a(new foo);
auto b = a;
...
// Eventually:
a = b;
This is not self-assignment as &a != &b
. The Copy&Swap does involve an unnecessary modification of the reference counter.