
"Andrea Torsello" <torsello@dsi.unive.it> 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!
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"?
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.
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?
My use-case was a vector-like container that increases but never decreases the size of its backing store. In order to provide the never decreasing backing-store semantic, operator = moves the backing store from a temporary only if the new data does not fit in the existing space. Hence, operator = must be able to discriminate between temporaries and non-temporaries.
My solution allows discrimination between temporaries and non-temporaries.
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? -- Dave Abrahams Boost Consulting http://www.boost-consulting.com