
"Peter Dimov" <pdimov@mmltd.net> escribió en el mensaje news:003201c51395$4f587820$6501a8c0@pdimov2...
David Abrahams wrote:
Jody Hagins <jody-boost-011304@atdesk.com> writes:
It seems to me that implementing the canonical assignment operator would work fine...
optional & operator=(optional const & rhs) { optional tmp(rhs); optional_swap(*this, tmp); return *this; }
I wish people would stop calling it that. It's easy, but it's overkill.
No, it is not overkill. It is the easiest way to implement a correct assignment operator. Forget performance. Subtle bugs in assignment are notoriously hard to find. To give the "canonical" example:
optional& operator=( T const & t ) { // destroy and recreate }
Consider what happens when an optional holds a tree node and is assigned a child of that node. Or in general, when the 'destroy' step indirectly destroys the right hand side.
Well, I would be surprise if T were so unlike a POD to have this sort of issues... but well, who knows. I would recommend shared_ptr<> in that case, but, well, maybe genericity get's in the way. I just looked closer at optional_swap() and it offers no exception-safety guarantees at all... It just does whatever T's swap() does. operator=() was designed to give a basic guarantee in spite of T. Thus, as I replied to Joe, changing the implementation means loosing the basic guarantee and leave it up entirely to T... I'm not sure how much good or bad that is... but I do remember that it was designed like that on purpose after long discussions here.. or at least that's what I concluded from those discussions ;)
A correct assignment operator should typically handle self-assignment without an explicit test. Adding the test usually doesn't fix the problem, only its most obvious manifestation.
Which could be accounted as good enough for classes intended to be used in certain ways, thus making the swap idiom overkill. Fernando Cacciola