Boost logo

Boost :

Subject: Re: [boost] [xint] Third release is ready, requesting preliminary review
From: Giovanni Piero Deretta (gpderetta_at_[hidden])
Date: 2010-05-04 11:36:35


On Tue, May 4, 2010 at 4:16 PM, DE <satan66613_at_[hidden]> wrote:
> on 04.05.2010 at 15:30
>  Stewart, Robert wrote :
>
>> DE wrote:
>>>  Giovanni Piero Deretta wrote :
>>>
>>> > No, but swap is your friend:
>>>
>>> > X operator- (X x) {
>>> >  modify-in-place x;
>>>
>>> >  X ret; // this should be cheap
>>> >  ret.swap(x);
>>> >  return ret; // NRVO should kick in
>>> > }
>>>
>>> i don't think it is a good idea to write such curious code in chase of
>>> a _possibility_ (there are no guarantees) of rvo
>
>> That's perfectly reasonable code.  Consider
>> <http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/>.
>
> i've read the article (rather boring one)
>
> i don't understand how is that different to
>
>  X operator- (const X &x)
>  {
>    X ret(x);
>    //modify 'ret'
>    return ret;
>  }
>

Then you haven't read the article carefully enough ;)

The idea is that rvalues passed to operator- (like in Peter's example)
won't be copied due to elision of temporaries. Only lvalue parameters
will be copied (you can't avoid that of course), while in your example
you have an unconditional copy to initialize ret.

>
> what about idiomatic
>
>  return X().swap(x);  //x is modified
>

my swap functions (and IIRC standard container swap functions) usually
return void so it won't work in generic code, but if it works for your
case, sure. Usually I refactor the pattern in a function like this:

template<typename T>
T move_swap(T& x) { // T is default constructible and swappable
   T ret;
   using std::swap;
   swap(x, ret);
   return ret;
}

So your operator- would look like this:

X operator- (X x)
{
   modify x;
   return move_swap(x);
}

-- 
gpd

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