From: David Abrahams (dave_at_[hidden])
Date: 2004-04-18 16:14:24
David Abrahams <dave_at_[hidden]> writes:
> So I'm wondering if there's a way to combine the advantages of your
> approach with those of mine.
The code in the sandbox now appears to be supporting both approaches.
I've also added disable_if_same.
Use the BOOST_LVALUE_COPY_CTOR2 and BOOST_LVALUE_ASSIGN2 macros to
auto-generate constructor/assignment overloads taking const_lvalue<T>
instead of using the template technique. Let's call that "technique 2".
Aside from the easier time you'll have getting partial ordering of
constructors and assignment operators with technique 2, I noticed the
The use of the 'explicit' keyword for a T const& ctor overload seems
to be completely unneccessary. All the optimizations you can get in
intel's strict mode are available using an ordinary non-explicit copy
ctor. Am I missing something?
In non-strict mode (and on Intel 8/win32) technique 2 seems to
generate copies when constructing from const rvalues whereas
technique 1 does not.
Technique 2 seems to require most compilers to go through move
constructions in situations where technique 1 allows the compiler to
elide copies. That could bring a significant speed penalty for some
types, unless optimizers are smart enough to eliminate the code later.
Not having a real T const& parameter for const lvalues makes writing
overloads tricky. I was able to make the macros transparent for
operator=, but because of initializer lists there's no way to do the
same thing for constructors. const_lvalue<T> now has a conversion to
T const&, so you can use boost::implicit_cast<T const&>(rhs) to get
a reference to the argument with uniform syntax.
Borland doesn't seem to be able to cope with technique 2. It
complains that operator= is ambiguous. I didn't try very hard to work
around the problem, though.
This code has been tested on win32 with the following compilers.
Where the techniques differ, results are shown as
como-win32 3 suboptimal copies in strict mode. With
in non-strict mode, 0/1 suboptimal copies
with 1/3 warnings.
cwpro8 0/1 suboptimal copies
gcc 2.95.3, 3.2, 3.3.1 0 suboptimal copies
bcc564 2/? suboptimal copies
<<< can't handle technique 2 yet >>>
msvc 6, 7, 7.1 0 suboptimal copies (**)
vc7 issues a couple of bogus warnings (C4927)
intel8 0/1 suboptimal copies (**)
intel5 intel6 intel7 2 suboptimal copies (**)
(**) On these compilers, non-copyability isn't automatically inherited
from movable<T>, i.e. the boost::noncopyable trick doesn't
work. Rvalues are silently bound to non-const references.
-- Dave Abrahams Boost Consulting http://www.boost-consulting.com