$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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".
Findings
--------
Aside from the easier time you'll have getting partial ordering of
constructors and assignment operators with technique 2, I noticed the
following:
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.
Results
-------
This code has been tested on win32 with the following compilers.
Where the techniques differ, results are shown as
#technique1/#technique2.
como-win32              3 suboptimal copies in strict mode.  With
                        -DBOOST_IMPLICIT_MOVE_CTOR_FOR_COPYABLE_TYPES
                        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