Boost logo

Boost :

Subject: Re: [boost] [operators] A modern SFINAE-based version of boost::operators?
From: Daniel Frey (d.frey_at_[hidden])
Date: 2017-11-15 15:30:41


> On 15. Nov 2017, at 00:04, Gavin Lambert via Boost <boost_at_[hidden]> wrote:
>
> On 15/11/2017 07:16, Daniel Frey wrote:
>> Before looking at those cases, consider a commutative operator+ (abbreviated version):
>> T operator+( const T& lhs, const T& rhs ) { T nrv( lhs ); nrv += rhs; return nrv; } // v1
>> T&& operator+( T&& lhs, const T& rhs ) { lhs += rhs; return std::move( lhs ); } // v2
>> T&& operator+( const T& lhs, T&& rhs ) { rhs += lhs; return std::move( rhs ); } // v3, remember: we assume a commutative +
>> T&& operator+( T&& lhs, T&& rhs ) { lhs += rhs; return std::move( lhs ); } // v4
>
> Given that NRVO is mandatory now, isn't it just as efficient and more correct to declare these as:
>
> T operator+( const T& lhs, const T& rhs ) { T nrv( lhs ); nrv += rhs; return nrv; } // v1
> T operator+( T&& lhs, const T& rhs ) { lhs += rhs; return lhs; } // v2
> T operator+( const T& lhs, T&& rhs ) { rhs += lhs; return rhs; } // v3, remember: we assume a commutative +
> T operator+( T&& lhs, T&& rhs ) { lhs += rhs; return lhs; } // v4
>
> (You could save a little typing by using "return lhs += rhs;" but that's probably not a good idea as you're left to the whims of compiler inlining whether it triggers some kind of RVO or not.)
>
> Unless I'm missing something?

You are confusing optimising away copy-operations with optimising away the temporaries altogether. Think of a class that does not benefit from move, e.g. a small matrix class holding its values directly.

>> a) Explicitly binding to a reference "to prolong the lifetime of the temporary".
>> This happens if you write
>> const T& t = t1 + ( t2 + t3 ) + t4;
>> As the last operator+ return an rvalue reference instead of an rvalue, the "const T& t =" does not bind to a temporary. The intermediate temporary created by (v2+v3) is destroyed at the end of the expression, hence t is now a dangling reference. Oops.
>
> The above would fix this, and your other case.

Yes, but at a cost. More moves, which become copies if the class can not benefit from move. Even if it can, moves still do have *some* cost, removing the temporaries completely eliminates that cost.




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