- What does "move its value to another location" really mean?
It means that the other location has the value that the original had prior to the move, and that it is not important what value the original location has after the move.
- How can a value (a bit interpretation) be moved?
For example, simply by copying. If one wanted to do extra work beyond that (which is not motivated with just a bag of bits), one could set the original location to some other bit pattern, such as all zeroes, and it would still be considered a successful move. The difference here with copying is that a copy should leave the original unchanged.
- How can bytes of an object be "moved" without a copy? Just doesn't make sense.
A copy is a valid move.
Sometimes the bits in the original have semantics of owning a resource. If there is only one resource, and you simply copy the bits, now both locations "own" the resource, resulting in duplicate disposing of said resource when both objects go out of scope.
So a move would transfer ownership of the resource to the new location and change the original location to not own a resource. A concrete example of this is an owning pointer: copy the pointer then set the original to nullptr
.
A copy might be more expensive than a move (and it might not). But continuing with the owning pointer example: If you make a copy of that object, then after the copy, two resources must exist (assuming unique ownership of the resource).
So a copy doesn't copy the pointer. The copy copies the resource and then the new location points to the new resource. If the creation of that resource is expensive, then a move can be much cheaper by just copying the pointer and nulling the original.
Generally speaking, move should be an optimization of copy when the type supports both operations. move should never be more expensive than copy. And if move has the same expense as copy, then the move operations can simply be not implemented and copy will handle moves seamlessly. It is up to the author of each type to maintain this paradigm.
For scalars (ints, pointers, doubles, etc.) copy and move are the same thing: copy the bits, don't alter the source.
std::string
is "foobar", but the bits that compose "foobar" aren't actually inside thestd::string
object. That's very key to understanding move semantics. – Coadunate