While reading some articles about the std::move semantics and the rvalue references, I came to know that they were introduced because copying data is an expensive job. True ! Copying is expensive but isn't that the same reason why we have "REFERENCES" in C++. They also just help pass the address of a variable and prevent the expensive procedure of copying.
Then why have std::move and rvalue been introduced ? I mean what job couldn't normal references do which the former ones could do ?
My question extends mainly to functions. I mean when you pass a variable to a function, which is better & why ? :- 1. Pass by lvalue reference 2. Pass by rvalue reference using move
Move semantics is there for situations when you have to copy data, i.e. when there's no way around it. The data has to "appear" in a new location, in a new object. I.e by design, the physical relocation/re-creation of data absolutely has to take place. Normal references don't cover this in any way. For example, when you add an element to a
std::vector
the element's value supplied by you also has to be appear in the new vector's element somehow.Most of the time in classic C++ this was achieved by unconditionally copying data to the new location. However, it was rather obvious that in some cases we didn't really care about the fate of the original object, from which that data was copied - the original object was destroyed immediately after copying anyway. Naturally, it presented a rather obvious and huge optimization opportunity: since we didn't care about the original object, we could simply "steal" (move) data from it, place that data into the new location and then destroy the (now empty) original. This is significantly more efficient that meticulously "cloning" (copying) the data and destroying the original.
We used to take advantage of this optimization opportunity even in classic C++. But we had to do it manually, without support from the core language. Move semantics and rvalue references is how this support was introduced into the core language, this opening this optimization opportunity to the compiler itself.
In other words, move semantics does not "eliminate copying". It optimizes copying by taking advantage of the fact that the sequence
src
todst
src
can be equivalently replaced by a much more efficient sequence
src
dodst
, makingsrc
"empty"src