|
Boost : |
From: Howard Hinnant (hinnant_at_[hidden])
Date: 2002-02-04 20:07:51
On Monday, February 4, 2002, at 07:37 PM, Jon Kalb wrote:
> Is move what we really want? Or is it swap? I've thought for awhile that
> swap was a missing "operator." It seems to be such a fundamental
> operation.
I agree 100% that swap is fundamental, and I would love to see a swap
operator. I suspect we're talking about the "next" language, but you
never know. However, I think move is even more fundamental than swap.
Consider: if scalars support move semantics (as they do swap), then
"moving" a scalar would be 3 times as expensive as you need:
template <class T>
void
swap(T& a, T& b)
{
T tmp(a);
a = b;
b = tmp;
}
Three assignments instead of one!
However if moving a scalar could be accomplished by a single assignment,
then swap could be built on top of move:
template <class T>
void
swap(T& a, T& b)
{
T tmp(move(a));
a = move(b);
b = move(tmp);
}
(courtesy Andrew Koenig)
And if move is /defined/ to be a non-throwing operation, then unlike the
current std::swap, this version built on move could be immediately
applicable to every class that implemented move semantics *and* be
non-throwing.
> I think it is clear what swap means, but I'm not certain that it is
> always going to be obvious what the state of an object is that has been
> "moved from." Does it assume the state of the default value? What if
> there is no default constructor? What if the default constructor does an
> allocation in preparation of storing data? Would that mean that move
> could fail?
My vote would be that if you can't move without throwing, then you can't
move. Not every class can support move, just as not every class can
support copy. And as for the value of a object that has been moved
from, I think that should depend upon the object. Might be cool (not
100% thought through!) if the value of a scalar moved from is
indeterminate:
int i = 0;
int j = move(i); // i is indeterminate now
This would allow compilers that do register coloring to do this move
with 0 cpu cycles! Simply rename the register from i to j. On the
practical side, I'm not sure how important this would be in practice as
in this scenario, one usually wants to move something into i in the next
statement (e.g. swap).
> What I am saying is that I think swap semantics accomplish what you want
> to accomplish with move, but is "more fundamental." Herb Sutter has
> convinced me that if I want to write exception safe code, I need to
> create a swap operation anyway and if I could use that operation to
> accomplish what you want to accomplish with move, I think it's a win.
I agree that we could do move with swap. I just think it would be
higher quality to do swap with move.
-Howard
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk