
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
Daniel Frey <d.frey <at> gmx.de> writes: 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.