From: David Abrahams (dave_at_[hidden])
Date: 2004-04-16 09:53:34
Andrea Torsello <torsello_at_[hidden]> writes:
>>> 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
>> I'm not sure what you mean, but AFAICT case #2 is handled just fine
>> by conforming compilers. Did you read
So did you?
>> It's a question of interpretation of a particular clause of the
> 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.
> 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."
The comment was wrong; either behavior could be interpreted as correct
if you stretch, but Comeau's is arguably too
restrictive. Unfortunately there's no macro we can use to detect
strict mode on EDG; it might mean that the implicit move optimization
needs to be turned off for certain cases with those compilers.
> 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.
There is never a need to pass a temporary by const ref if you can
>>> 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.
> 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
You don't have to do that; you can use two overloads, one of which
takes references and the other of which takes move_from<T>.
>> My solution allows discrimination between temporaries and
> It certainly does on copying, but does it allow to pick different
> overloaded functions when passing a temporary and a non-temporary?
template <class T>
enable_if_same<T const, X const, void> f(T&); // lvalues
void f(move_from<X>); // temporaries
> 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.
Why don't you do some research? It's all in the sandbox.
>>> 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.
I still don't understand why you think it's important to distinguish
const temporaries from const lvalues.
-- Dave Abrahams Boost Consulting http://www.boost-consulting.com