Reputation: 745
I'm wondering what happens when I have a function like this:
typedef std::unordered_map<std::string,std::string> stringmap;
stringmap merge (stringmap a,stringmap b)
{
stringmap temp(a); temp.insert(b.begin(),b.end()); return temp;
}
what happens when the function returns?
Is 'temp' copied to a temporary r-value before being destroyed (out-of-scope) and with C++11 possibly NRVO-ptimized (so the copy of 'temp' is directly written to the return destination slot)?
Upvotes: 5
Views: 388
Reputation: 110658
This would typically, without any special rules, result in a copy from temp
to the return value of the function. However, there are two rules in the standard that aim to improve this. The first is that the copy may be elided (12.8/31):
in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function or catch-clause parameter) with the same cvunqualified type as the function return type, the copy/move operation can be omitted by constructing the automatic object directly into the function’s return value
This is often known as named return value optimization (NRVO), a special case of return value optimization (RVO).
The second is that, since this situation meets the above criterion for copy elision, it will first be considered as a move (12.8/32):
When the criteria for elision of a copy operation are met or would be met save for the fact that the source object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue.
So the compiler will attempt the following steps:
Note that the class has to have either a move or copy constructor for this to work, even if the move or copy is elided.
Upvotes: 4
Reputation: 254461
Nothing should be copied. There are two possibilities:
temp
is moved to an object in the caller's scope; ortemp
becomes an alias for an object in the caller's scope. This is known as "return value optimisation".Before 2011 (specifically, without move semantics), the first case would require a copy rather than a move. The second case was allowed in C++98 as well as 11.
Upvotes: 7
Reputation: 88155
NRVO would mean that temp
itself is constructed in the return value location. Without RVO, yes, temp
is copied/moved from its location on the stack into the return value location prior to being destroyed.
Upvotes: 5