On 2010-10-06 12:34:54 -0400, Andrei Alexandrescu
<seewebsiteforem...@erdani.org> said:
To solve that problem, I introduced moveFront(), moveBack(), and
moveAt(size_t), all of which destructively read the front, back, or an
indexed element respectively off the range. Then you can swap r1.front
with r2.front at constant cost like this:
T tmp = r1.moveFront();
r1.front = r2.moveFront();
r2.front = move(tmp);
All of this works and is rock-solid, but it does load the range
interface considerably. To a newcomer coming without the background
above, a full-fledged range definition may look quite loaded.
I think like you that this does not belong in the range interface. You
are illustrating quite well that it's not the right layer to solve the
problem.
But I don't think saying "move semantics are too complicated to
implement, let's forget them for range" is a solution either. If you
start this with ranges, then it'll continue for other things that'll
also suffer from the same problem, and move semantics will not be very
usable anywhere.
But improving move semantics would probably require some language
changes and there seem to be little interest with that currently, so
I'll leave it at that and go to the second point...
One simplification is to simply decree that Phobos (and D in general)
shuns objects with eager copy. Any this(this) could be considered
constant cost.
Not a bad idea in itself. But while it makes "move" less needed, a
dependence on the ability to copy in algorithms will prevent them from
working with non-copyable structs.
Could algorithms use "move" when possible (when "front" returns a ref)
and do a copy when move isn't available? That'd be a good compromise I
think.
T tmp = moveOrCopy(r1.front);
r1.front = moveOrCopy(r2.front);
r2.front = moveOrCopy(tmp);
--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/