Topic: adding "move" to c++
Author: chris@bubblescope.net (chris)
Date: Thu, 7 Oct 2004 17:36:00 GMT Raw View
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm
discusses the possibility of adding a "move" to c++, which would allow
for more efficent implementations of a number of algorithms that c++
implements.
It also discusses implementing std::swap with this move, but I think
this may be misleading.
Assuming that a=static_cast<T&&>(b) (the notation used) moves b to a and
promise to leave b in a valid (if undefined state), then to implement
this without extra features I would use a(b) except in those cases where
an efficent swap exists, and then use swap(a,b).
It is not obvious to me how move could be made more efficent than one of
these two, assuming the class was designed to make both a(b) and
swap(a,b) as efficent as possible.
And if this is true, could it not simply matters to say that move will
either perform a swap or copy constructor?
Thank you,
Chris
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hinnant@metrowerks.com (Howard Hinnant)
Date: Thu, 7 Oct 2004 22:15:32 GMT Raw View
In article <ck38n2$7ja$1@pump1.york.ac.uk>,
chris@bubblescope.net (chris) wrote:
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm
> discusses the possibility of adding a "move" to c++, which would allow
> for more efficent implementations of a number of algorithms that c++
> implements.
>
> It also discusses implementing std::swap with this move, but I think
> this may be misleading.
>
> Assuming that a=static_cast<T&&>(b) (the notation used) moves b to a and
> promise to leave b in a valid (if undefined state), then to implement
> this without extra features I would use a(b) except in those cases where
> an efficent swap exists, and then use swap(a,b).
>
> It is not obvious to me how move could be made more efficent than one of
> these two, assuming the class was designed to make both a(b) and
> swap(a,b) as efficent as possible.
>
> And if this is true, could it not simply matters to say that move will
> either perform a swap or copy constructor?
^
did you mean assignment? Assuming you did...
If we are only going to discuss (move) assignment, I agree with you 100%.
But there are other cool applications for move semantics besides just
improving the efficiency of assignment.
The next most obvious is move construction, which a class might
implement as a default construction followed by a swap. Or it might
even more efficiently implement as a memcpy followed by a memset to 0
(just for example).
And then there is the vector::push_back example. Wouldn't it be cool if
you could say:
MyHeavyClass x;
vector<MyHeavyClass> v;
v.push_back(move(x));
Moving, instead of copying x into the vector. In this latter example,
it is not immediately clear the algorithm move() should be using to help
the vector move x into itself, instead of copy it in.
N1377 / N1690 propose a system by which move(x) is really nothing more
than telling the compiler to treat x as an rvalue. And also changing
the language so that programmers can overload on lvalue/rvalue.
As it turns out, it is always safe to move from an rvalue, even with
copy syntax. So if vector<T>::push_back(t) can be overloaded for lvalue
t and rvalue t, then the rvalue overload can do the move dance
internally, leaving the lvalue overload to do the usual "copy into
vector" algorithm. At this point, lvalues will always be
copy-push_back'd into a vector and rvalues will always be
move-push_back'd in. Now all that's needed is a way to say "for this
one lvalue, treat it as an rvalue instead this time".
And that's all move() does.
-Howard
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Thu, 7 Oct 2004 22:15:51 GMT Raw View
chris wrote:
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm
> discusses the possibility of adding a "move" to c++, which would allow
> for more efficent implementations of a number of algorithms that c++
> implements.
Doing "move" via
static_cast<A&&>
seems too ugly to put in the core language.
We need to be able to talk about variable lifetime in the
language. Adding another backdoor around the typing system
is not the answer.
I've made some suggestions in my "strict C++" proposal,
where I proposed that "auto" references only be assignable
to objects of longer lifetime than the destination.
Most of the objections came from people who want to use
the "auto" keyword for something else.
It's OK to bind a reference to a temporary only
if you're sure the reference won't outlive the temporary.
This is checkable at compile time. So if we do something
like this, it should be checked at compile time.
int x;
int& rx = x; // OK
{ int y;
rx = y; // ERROR - ref outlives temp
}
Arguably, that check should be the default.
It would be interesting to put that check in a compiler
and recompile some big systems, to see what breaks.
John Nagle
Animats
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Sun, 10 Oct 2004 20:09:01 GMT Raw View
John Nagle wrote:
> It's OK to bind a reference to a temporary only
> if you're sure the reference won't outlive the temporary.
> This is checkable at compile time. So if we do something
> like this, it should be checked at compile time.
>
> int x;
> int& rx = x; // OK
> { int y;
> rx = y; // ERROR - ref outlives temp
> }
Sorry, I don't understand this example. "rx = y" does not rebind rx, but
copies the value of y into x. I see no "outliving" problem when y goes
out of scope, because y is not being bound to a reference. The only
problem I see in this code is the use of the value of y without y being
initialized ;-)
Could you please clarify your thought?
Alberto
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Tue, 12 Oct 2004 16:14:31 GMT Raw View
Alberto Barbati wrote:
> John Nagle wrote:
>
>> It's OK to bind a reference to a temporary only
>> if you're sure the reference won't outlive the temporary.
>> This is checkable at compile time. So if we do something
>> like this, it should be checked at compile time.
>>
>> int x;
>> int& rx = x; // OK
>> { int y;
>> rx = y; // ERROR - ref outlives temp
>> }
>
>
> Sorry, I don't understand this example. "rx = y" does not rebind rx, but
> copies the value of y into x. I see no "outliving" problem when y goes
> out of scope, because y is not being bound to a reference. The only
> problem I see in this code is the use of the value of y without y being
> initialized ;-)
That's correct; you can't directly reassign a reference. You have
to return a reference to get into trouble.
Are there troublesome cases here that can't be detected at
compile time? Since references can't be reassigned, the compiler knows
the scope of the target of a reference at compile time, and should
be able to reliably prevent the return of an out of scope reference.
John Nagle
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: wade@stoner.com (Bill Wade)
Date: Wed, 13 Oct 2004 20:41:03 GMT Raw View
nagle@animats.com (John Nagle) wrote
> Are there troublesome cases here that can't be detected at
> compile time? Since references can't be reassigned, the compiler knows
> the scope of the target of a reference at compile time, and should
> be able to reliably prevent the return of an out of scope reference.
static T t;
T& foo(T& x){ return rand()&1 ? t : x; }
T& bar(){ T y; return foo(y); }
foo() never returns an out-of-scope reference.
To know if bar() returns an out-of-scope reference, the compiler has
to look at the internals of both foo() and rand(). Even then it may
not be able to answer the question at compile time.
Of course, out-of-scope isn't the only possible problem. Object (and
memory) lifetime isn't strictly tied to scope.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]