
On Sun, 28 Apr 2013, Daniel Frey wrote:
after some more experiments, I convinced myself that I should explore the option of returning an rvalue (not an rvalue reference) in all cases when implementing operator+ based on operator+= (as an example). But I wonder what the most efficient overload set would look like. With this post I'll concentrate on same-type operations (T+T).
Given a class T with operator+= like this:
T& T::operator+=( const T& ); T& T::operator+=( T&& ); // if useful the class provides it and it should be used if applicable
I think the following is currently the best overload set for operators:
T operator+( T lhs, const T& rhs ) { lhs += rhs; return lhs; // no std::move needed }
Splitting this into const& and && overloads of lhs would save a move for: T r = std::move(a) + b; (passing an xvalue and not a prvalue) In practice, it would also save a move for T r=a+b, although in theory it shouldn't (it should cost one extra move instead), but compilers are bad at eliding the copy between an argument and the return (it would be a cross-function optimization in the front-end). Sometimes you would want to overload on lvalue vs xvalue vs prvalue for optimal results, but the language will not allow it.
T operator+( T&& lhs, T&& rhs ) { lhs += std::move( rhs ); return std::move( lhs ); }
T operator+( const T& lhs, T&& rhs ) { #ifdef COMMUTATIVE rhs += lhs; return std::move( rhs ); #else T nrv( lhs ); nrv += std::move( rhs ); return nrv; #endif }
-- Marc Glisse