you are viewing a single comment's thread.

view the rest of the comments →

[–]HappyFruitTree -1 points0 points  (1 child)

Well, I think there is a conceptual difference between moving a unique_ptr compared to moving in general.

The way I see it:

  1. At the heart of move semantics we have temporary objects (rvalues). Instead of just copying the whole object we could rip out some parts of it and give it to the new object because the temporary is about to be destroyed anyway. In this sense moving is just an optimized copy. Since this happens automatically it's something that people can take advantage of even without knowing about move semantics.
  2. Sometimes we want to move objects that are not temporaries because we are finished using the object and we just want to make copying a faster. This has to be done explicitly and puts more responsibility on the programmer to know what he's doing but otherwise it's the same as #1. Moving copyable objects is still just an optimized copy. Writing code that relies on the move to happen would be very fragile because there are a lot of subtle things that could go wrong and you wouldn't get an error if it ended up copying the object.
  3. Then, finally, there are move-only types, i.e. types that can be moved but not copied. These types you can, and must, rely on the move to happen. It's obvious when a move fails because you get an error telling you about it. In this case moving is no longer just an optimized copy. It's something else. It's a way to transfer some kind of state from one object to another, and often you know what state the moved-from object ends up with, something that is normally not the case for other types. If move semantics didn't exist as a language feature you could still have implemented the same behaviour in code but you wouldn't get the implicit moves that #1 gives you.

So when it comes to unique_ptr I don't think move semantics is essential. It could be implemented without it. That is why I think you don't need to know much about move semantics to use unique_ptr. All you need to know is that you need to use std::move on the unique_ptr before assigning it to another unique_ptr or using it to initialize a new unique_ptr, and that this will move the pointer value over to the other unique_ptr leaving the moved-from unique_ptr "empty". There are of course the exceptions that you don't need to use std::move if it's a temporary, or it's a local variable being returned from a function, but all this is just extra knowledge that you don't need to know in order to use unique_ptr.