In general I would like to know when and why a modern day compiler, say gcc 4.7 and up using c++11, can not apply an NVRO optimization.
EDIT: I oversimplified this code mistakenly not returning any local variables. A better example was supplied by @cooky451 below see ideone.com/APySue
I saw some snippets of code to answers on other questions that were as such
A f(A&& v)
{
return v;
}
and they were changed to be
A f(A&& v)
{
return std::move(v);
}
because they said that the rvalue passed in which is assigned to an lvalue v was still an rvalue and could be moved. However, others wrote that this will remove the ability for NVRO. Wny is this? If the compiler knows that a temporary is being returned can't it construct it directly in place without moving anything? I guess I don't understand why case one would have NVRO but not case 2. I might have the facts wrong hence the question. Also, I read that case 2 was an anti pattern for this reason and that you shouldn't return std::move like this. Any additional insight would be helpful. I was told that behind the scenes the compiler will create something like this below: A& __hidden__
is the assignment to the function, myValue in this case.
A myValue = f(A());
// behind the scenes pseudo code for direct in place construction
void f(A&& v, A& __hidden__ )
{
__hidden__ = v;
return;
}
Both won't use RVO, because it's impossible. The problem is: && is still just a reference. The variable you're returning is not inside your function-local scope! So, without std::move, you'll copy, and with it you'll move. I would advice btw not to expect something per rvalue-reference, as long as you're not writing a move constructor/assignment operator or some perfect-forwarding template-code. Just take it by value. It has a small overhead in some cases, but it's really not going to be significant. And it makes code a lot more readable. And simpler, as the caller can either copy or move the arguments, and you don't have to provide additional const& overloads.