On 15. Nov 2017, at 00:04, Gavin Lambert via Boost
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.