Boost logo

Boost :

From: Andrea Torsello (torsello_at_[hidden])
Date: 2004-04-17 08:37:41

"David Abrahams" <dave_at_[hidden]> writes:
> By the way, if you are willing to give up on move semantics from
> direct initialization, my technique will work in Comeau strict mode
> just as well as yours. Nothing about what you did will get around
> that problem; it seems to be a fact of current EDG compilers that in
> strict mode direct initialization from an rvalue will only ever use an
> ordinary (T const&) copy ctor.

    void sink(X const &);
    X source();
    void foo() { sink(source()); }
on Comeau strict does not compile...
everywhere else it does.

> Please do. Also please use the latest version of the code in the
> sandbox to test against.

Last test was a couple of months ago when I was working activly on this,
will do on most recent version I can find

As I said on another message, my moving class was parametrized on templated
type Tp
and had a converting constructor and operator =

    template<class U> explicit X(X<U> const &);

there is the solution

    template<class U> explicit X(X<U> const &,

but adds extra requirements on unrelatd features.
The same applies to the enable_if_same<T const, X const, void>::type return
type for non
temporary overloaded functions. It looks like my approach doesn't do
anything your approach
cannot do (not surprisingly since the only difference is in the technique I
use to make X(X const &)
less "priviledged" than the other constructors), but it appears to have less
interactions with other
language features. And hence less requirements on the library user.

> Actually I'm not sure what I was trying to say anymore. I can state
> that my library already allows
> sink(source());
> to work transparently with move semantics on all compilers I've
> tested on.

as stated before if sink is "void sink(X const &);" Comeau in strict mode
complains that there is no X(X const &) constructor.

> Sorry, that wans just a mistake; it isn't convertible to anything. I
> meant:
> template <class T> // lvalues
> typename enable_if_same<T const, X const, void>::type f(T&);
> void f(move_from<X>); // temporaries

Oh, OK that would work with operators as well, still with my approach it
would be:

void f(X&);
void f(X::constant);
void f(X::temporary);

which, to me, seems easier from the user perspective. Clearly, this is just
a matter of taste.

> Exactly. Or you could just use explicit instantiation. BTW I assume
> you mean "templated function".

Yes sorry.

> It's no worse a problem than replacing what should be a reference
> paramter with another type that can be constructed by implicit
> conversion. You still cut off the possibility of user-defined
> conversions.

Yes. I was not claiming that forcing a templated function was an
unsurmoutable problem,
obviously there are ways aroud it. But think from the perspective of the
user: even if you
hide the details of the function definition with macro tricks, suddenly the
user cannot keep
the function on a separate compilation unit unless the macro manages to
perform the
explicit instantiation as well, which would be hard since you should
explicitly instantiate two
specializations: one for type X and one for type X const.

> I don't see any advantages yet.

Nothing your approach doesn't allow with some work (except Comeau not
allowing to pass
by const reference), but less interactions with orthogonal language
featuresthe user should
know about.
The only problem I have encountered so far comes from
    X x(makeX());
calling the explicit copy constructor (X x=makeX(); does not).
While in this case the approach fails to move, it is by far the easyest case
for compiles to
perform return value optimization. The only compiler I have seen not
performing the optimization
is Comeau in strict mode.

> I didn't take it that way. I'm not arguing with you out of
> defensiveness. If you really think what you did had some advantages,
> I want to be convinced of them so I can change my library to be the
> best possible.

Glad to hear it, email are so easy to misunderstand... Sorry if I
misunderstood you,
I apologize, but I really wrote because I think this might be useful.

> >> I still don't understand why you think it's important to
> >> distinguish const temporaries from const lvalues.
> >
> > As you said in another post, it is not a problem to move from a const
> > temporary (the compiler might just copy the const temporary to a non
> > const temporary and optimize the copy away), hece you want to move
> > from const temporaries.
> Which my library does.

Never claimed it does not.

> > On the other hand, you should certainly not move from lvalues.
> OK, but in that case I don't see why you want to distinguish const
> temporaries from non-const temporaries.

I don't. As a matter of fact I never really tested that before because I
never returned a
const temporary in my career. I added it to the test on the final version
for completness,
but I don't really care either way, since for the life of me I cannot find a
use-case for
const temporaries.

Best Regards
Andrea Torsello

Boost list run by bdawes at, gregod at, cpdaniel at, john at