As far as I understand one of the purposes of adding move semantics is to optimize code by calling special constructor for copying "temporary" objects. For example, in this answer we see that it can be used to optimize such string a = x + y
stuff. Because x+y is an rvalue expression, instead of deep copying we can copy only the pointer to the string and the size of the string. But as we know, modern compilers support return value optimization, so without using move semantics our code will not call the copy constructor at all.
To prove it I write this code:
#include <iostream>
struct stuff
{
int x;
stuff(int x_):x(x_){}
stuff(const stuff & g):x(g.x)
{
std::cout<<"copy"<<std::endl;
}
};
stuff operator+(const stuff& lhs,const stuff& rhs)
{
stuff g(lhs.x+rhs.x);
return g;
}
int main()
{
stuff a(5),b(7);
stuff c = a+b;
}
And after executing it in VC++2010 and g++ in optimize mode I'm getting empty output.
What kind of optimization is it, if without it my code still works faster? Could you explain what I'm understanding wrong?
Just because this particular case is already covered by an existing optimization does not mean that other cases don't exist where r-value references are helpful.
Move construction allows optimization even when the temporary is returned from a function which cannot be inlined (perhaps it's a virtual call, or through a function pointer).
There are many places some of which are mentioned in other answers.
One big one is that when resizing a
std::vector
it will move move-aware objects from the old memory location to the new one rather than copy and destroy the original.Additionally rvalue references allow the concept of movable types, this is a semantic difference and not just an optimization.
unique_ptr
wasn't possible in C++03 which is why we had the abomination ofauto_ptr
.