Boost logo

Boost :

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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk