|
Boost : |
Subject: Re: [boost] [operators] What is the correct overload set for a binary operator?
From: Marc Glisse (marc.glisse_at_[hidden])
Date: 2013-04-28 11:52:59
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk