Boost logo

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