Boost logo

Boost :

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
>>> this).
>> 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
>> 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.


> 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
move it.

>>> 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

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
>> non-temporaries.
> 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

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