1

I'm trying to get my head around move semantics. I become confused because I couldn't find out why we need this and how should we use it ideally.

For example, when we move an object with by std::move, it makes the object nullptr. why does this happen? Also, why std::move turn an object to rvalue? how does this happen? Why after using std::move with a variable, it doesn't fill it with null, but when I use it with an object like vector, after moving it, it fills it with nullptr.

I hope, someone explaining the move semantics and other semantics of CPP step by step. The more I read about it, the more confused I become. It is one of the most complicated subjects of CPP programming.

1 Answers1

6

When we move an object with by std::move

No. std::move doesn't move things. It gives us an rvalue expression referring to some object. An rvalue expression results in overload resolution picking functions that take rvalue references, which is convenient because now we will pick those instead of the functions that take values, or lvalue references, which traditionally do copy-like things. Such functions tend to be constructors (so-called "move constructors") or assignment operators (so-called "move assignment operators") because it is during construction and assignment that moving is useful.

it makes the object nullptr

That depends entirely on what said function does. Typically, an object that's worth moving has indirect state, like a pointer to some dynamically-allocated resource. And if said object is moveable, its move constructor is best off doing a swap on those pointers. If it didn't leave the source object's pointer as nullptr then you have two objects owning the resource. That wasn't a move; it was a [shallow] copy.

A full discussion of the hows and the whys is out of scope of a Q&A, but any good book should have one.

Also, if this all sounds like a hack, that's because it is one. C++ is a hodge-podge of hacks built on hacks to provide additional functionality over time. In this case, we needed (read: wanted) a way to create a different kind of constructor (and assignment operator), a kind that would take a non-const reference and could modify the source object (to "steal" its resources), and to achieve that we had to introduce a new kind of reference that would only bind to rvalues (because we were already using everything else for copies), and then we had to introduce a utility function that would turn the name of an object into an rvalue … hence, std::move was born, the utility function that doesn't move anything.

Lightness Races in Orbit
  • 358,771
  • 68
  • 593
  • 989