Boost logo

Boost :

Subject: Re: [boost] Improving the assignment operators of various Boost types
From: David Abrahams (dave_at_[hidden])
Date: 2008-09-10 14:46:12


on Wed Sep 10 2008, Niels Dekker - mail address until 2008-12-31 <nd_mail_address_valid_until_2008-12-31-AT-xs4all.nl> wrote:

> Thanks for all of your feedback so far. I just started by submitting
> three tickets. Please double-check:
>
> #2311: any::operator= should have by-value argument
> http://svn.boost.org/trac/boost/ticket/2311#2312: intrusive_ptr::operator= should have by-value argument
> http://svn.boost.org/trac/boost/ticket/2312#2313: multi_index_container::operator= should have by-value argument
> http://svn.boost.org/trac/boost/ticket/2313
>
> Peter Dimov wrote:
>>> /if/ an assignment operator is implemented by means of
>>> copy-and-swap, it should preferably be done as follows:
>>>
>>> T& operator=(T arg)
>>> {
>>> arg.swap(*this);
>>> return *this;
>>> }
>>
>> This is well known (although the typical form is swap(arg)
>> instead of arg.swap(*this)).
>
> Is the choice between swap(arg) and arg.swap(*this)) just a matter of
> taste?
>
>> It is not widely used in Boost because it creates problems
>> with some compilers (I recall Borland being one). The "classic" form is,
>> unsurprisingly, much better supported across the board. Things may have
>> improved now, of course.
>
> Please let us know if there's a specific compiler version we need to
> support that wouldn't allow by-value argument for assignment operators.
>
>
> David Abrahams wrote:
>> In generic code I strongly prefer
>>
>> T& operator=(T arg)
>> {
>> swap(*this, arg);
>> return *this;
>> }
>
> I'm not sure... It might still compile when T wouldn't have a custom
> swap. If so, it would possibly pick the /generic/ boost::swap or
> std::swap, recursively caling the assignment of T and getting into an
> infinite loop.

Yuck.

> So it seems to me that its more safe to call the swap
> /member/ function of T, in this case.

Well, you have to know that the member exists in class T (and not in a
derived class), just as you have to know that the free function is
defined specifically for T, so I'm not sure it's a significant
difference. I'm just saying, I guess, that the form using the member
forces me to define a swap member even though it's not really needed by
generic code.

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk