Boost logo

Boost :

From: Andrea Torsello (torsello_at_[hidden])
Date: 2004-04-16 11:09:19


David Abrahams wrote:

> "Andrea Torsello" <torsello_at_[hidden]> writes:
>
>> Hi, I have been investigating move semantics and think that I came up
>> with a solution that is strongly influenced by both David Abrahams' move
>> approach and Andrei Alexandrescu's mojo, but solves some of the problems
>> I have encountered with them.
>> The basic idea is to use the explicit keyword to force the compiler to
>> use
>> the X(X const &) constructor only in two cases.
>> 1) When explicitly copying a const object i.e.
>> X const x;
>> X y(x); //use explicit copy constructor
>
> Not when passing a non-const lvalue?
>
> X x;
> X y(x); // implicitly uses a move ctor?? That's highly undesirable!

Actually, as described in a folowup, the approach works only with copy
initialization, not with direct initialization. Direct initialization
always uses the X(X const&) copy constructor. Not a major drawback in my
use-cases, but your milage may vary.

When using the copy initialization
X x;
X y=x;

the X(X&) constructoor is used.

>> 2) When passing by const ref
>> void f(X const &);
>> X makeX();
>> void foo()
>> {
>> f(makeX()); //use explicit copy constructor
>> }
>> In all other cases the other constructor take precedence.
> Which "other constructor"?

Should have been other constructorS.
i.e. X(X&) for non-const lvalues, X(X::constant) for constants and
X(X::temporary) for non-const rvalues.

>
>> Note that the template trick David Abrahams uses in his move
>> approach would lead to an error on a conforming compiler when
>> confronted with case #2 (unless more recent versions corrected
>> this).
>
> I'm not sure what you mean, but AFAICT case #2 is handled just fine by
> conforming compilers. Did you read
> http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2004/n1610.html?
> It's a question of interpretation of a particular clause of the
> standard.

Not sure about the standard's wording, but Comeau in strict mode fails to
compile the test you provided on this list some time ago.

http://lists.boost.org/MailArchives/boost/msg59826.php

Furthermore in the text of that test you added a comment after test 10, and
I quote
"// This one fails in Comeau's strict mode due to 12.2/1. GCC 3.3.1 passes
it erroneously."
Finally the need for X(X const &) to pass a temporary by const ref was the
reason that forced Alexandrescu to add the special return type to mojo.

>
>> I chose to keep the temporary and constant subtypes from mojo because
>> they allow me to discriminate between const values, non-const rvalues and
>> non-const rvalues.
>
> const and non-const rvalues are pretty much interchangeable, since the
> compiler can turn the former into the latter. If they weren't
> interchangeable, I don't see any reason you'd want to treat a const
> rvalue differently from a const lvalue.
>
>> The lack of this capability was the major problem I had with David
>> Abrahams' move.
>
> Why?

Passing by value is fine if you always move from temporaries and copy from
non-temporaries: you pass by value and move from the passed object. If,
like in the case of my vector-like container, you don't want to change the
backing store unless you have to, the pass-by-value-and-move approach is
not feasible

> My solution allows discrimination between temporaries and
> non-temporaries.

It certainly does on copying, but does it allow to pick different overloaded
functions when passing a temporary and a non-temporary? The code snipped
you sent on the quoted message doesn't appear to allow it, but as I said, I
am not sure about newer versions.

>
>> My solution fullfills almost all the requirements I had:
>> 1) passing by value moves non-const rvalues and copies everithing else.
>> 2) its is transparent to the user of the class.
>> Alexandrescu's Mojo fails this because of the special return type,
>> while
>> Abrahams' move fails it because of the pass-by-const-ref problem
>> described above.
>
> Please describe the problem in more detail.
>
>> 3) it allows to discriminate between constants, non-const lvalues, and
>> non-const rvalues.
>> Alexandrescu's Mojo allows it, while Abrahams' move does not.
>
> Why is that an advantage?
>
>

I Hope I explained the points clearly enough, but please contact me if you
have any doubt criticism or enquiry. I value all the feedback you can
provide.

Thanks a lot
Andrea Torsello


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