|
Boost : |
Subject: Re: [boost] [operators] What is the correct overload set for a binary operator?
From: Andrew Ho (helloworld922_at_[hidden])
Date: 2013-04-28 15:47:51
Daniel Frey <d.frey <at> gmx.de> writes:
> One remarks about the proposed full version of operators2.hpp: Andrew, I
really appreciate your work and
> enthusiasm, but please understand that IMHO this needs to be done step-by-
step and much more slowly than
> you probably hope for. Let's figure out the proper overload set for T+T
first, then T+U/U+T (again both
> commutative and non-commutative), noexpect-specifier for all overloads,
etc. After that, we need to
> decide on whether or not to improve the existing operator library or to
provide an independent V2. This
> might include rethinking the grouped templates. Using Boost.Move might
help with the implementation or
> not, depending on what overload set we want/need. It all needs tests and
documentation and it will be quite
> some work⦠hope you and others are still with me on this :)
>
That's fine, I was using that code as a test-bed to try and understand how
different features would fit together, and it really wasn't much work once I
had a cleaned-up base (I can re-use the same base with any
BOOST_BINARY_OPERATOR macro definition quite easily, some other changes may
be relatively easy to scale). I figured I might as well share my results to
demonstrate my findings (for example, I was curious as to how Boost Move
would fit in).
> Could someone please test this with VC++?
Yeah, I did some testing with VS2012 (/O2 optimizations) using your original
set and with Marc's set. Both work, but Marc's set does result in fewer
temporaries all-together. To be specific, all internal moves seem to be
optimized away, only move required is moving into the result variable. I
think this provides all of the benefits of your previous rvalue-ref code
without the unsafe behavior.
I got the same results testing with MinGW (GCC 4.7.2).
One interesting behavior I noticed while testing:
1)
MyClass operator+( const MyClass& lhs, const MyClass& rhs )
{
MyClass nrv(lhs);
nrv += rhs;
return nrv;
}
2)
MyClass operator+( const MyClass& lhs, const MyClass& rhs )
{
return std::move(MyClass(lhs) += rhs);
}
1) and 2) do not compile equivalently. 2) for some reason does not allow the
compiler to perform return value optimizations (at least the compilers I
tested with), potentially resulting in extra unnecessary temporaries.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk