The example from the standard is std::atomic. It returns the assigned value. If it returned reference, then reading through it might yield different result.
You are correct. Your version does not only work it is also more efficient since existing memory can be reused when ps->capacity() >= rhs.ps->capacity(). If you want to provide strong exception guarantees you should use the copy-and-swap idiom: HasPtrValue& HasPtrValue::operator=(HasPtrValue copy) // notice the by value { swap(*this, copy); return...