Possible Duplicate:
What happens if I return literal instead of declared std::string?
Consider the following code
string getName () {
return "meme";
}
string name = getName();
The function getName() returns a temporary object. In C++03, I understand the copy constructor of string gets called and the temporary object is destroyed. Actually it seems that the compiler (at least in GCC 4.7) optimizes line 5 by not creating the object name but replacing it with the temporary object itself and not destroying the temporary object. (I tried with a MyVector class, not std::string)
As defined in C++11 standards,
-
Is
getName()returning an rvalue? -
In line 5 above, which constructor of string gets called (move or copy) ? Should I necessarily call
std::move()for the move constructor to get called? -
With move semantics, is it less efficient then the “copy elision” optimization provided by the compiler?
Functions don’t return rvalues or lvalues. The value categories apply to expressions. So an expression that calls a function may be an rvalue or lvalue. In this case, the expression
getName()is an rvalue expression because the functiongetNamereturns an object by value. This comes from §5.2.2/10:Your functions result type is not an lvalue or rvalue reference, so the function call is a prvalue. prvalue expressions are a subset of rvalue expressions.
The move constructor will be used (unless it is elided, which it may be). That’s because
getName()is an rvalue, so the constructor ofstd::stringthat takes an rvalue reference will better match the argument. Note that even if the move construction is elided, the move constructor must still be accessible. That is, the code must be compilable even if it is not elided.In general, the optimization of copy or move elision will completely get rid of any copying or moving. So of course it’s faster than actually doing a move. If a move is elided, literally nothing happens. There will be no code emitted for that move. The compiler achieves this by directly constructing the object in the location it would be copied or moved to.
It’s worth mentioning that this could also be equivalently optimized:
Here, two moves will be elided (involving what is commonly known as Named Return Value Optimization). There are two points to consider here. First,
return str;meets the criteria for copy/move elision (§12.8/31):Second is that, although
stris an lvalue, it will still be moved from because it fits a special case given by the standard (§12.8/32):