Anders Knatten, a C++ developer, writes about the language's value categories, type system and quirks.
HN commenters recommend his explanation of lvalues, rvalues, glvalues, prvalues and xvalues as clear and helpful for understanding move semantics.
He has a good article on that at [1]
But here's the gist: sometimes you have an object you want to copy, but then abandon the original. Maybe it's to return an object from a function. Maybe it's to insert the object into a larger structure. In these cases, copying can be expensive and it would be nice if you could just "raid" the original object to steal bits of it and construct the "copy" out of the raided bits. C++11 enabled this with rvalue references, std::move, and rvalue reference constructors.
This added a lot of "what the hell is this" to C++ code and a lot of new mental-model stuff to track for programmers. I understand why it was all added, but I have deep misgivings about the added complexity.
[1] https://blog.knatten.org/2018/03/09/lvalues-rvalues-glvalues-prvalues-xvalues-help/
This is actually a very nice explanation!
I also enjoyed the linked article about the 5 value types: https://blog.knatten.org/2018/03/09/lvalues-rvalues-glvalues-prvalues-xvalues-help/. For some reason I never bothered to look up these terms as they sounded so obscure. Turns out the taxonomy is pretty clear and it's just a refinement of the existing two value types (lvalues and rvalues).
EDIT: I do think the naming is rather confusing and inconsistent, though.