RVO and NRVO work by constructing the object that is to be returned directly in the space provided by the caller, instead of constructing the object in the local variables of the function and then copying it over to the caller space.
Let's look at the sample.
Code:
RVO MyMethod (int i)
{
RVO rvo;
rvo.mem_var = i;
if (rvo.mem_var == 10)
return (RVO());
return (rvo);
}
The issue is this: the rvo object must be constructed before the assignment to mem_var. Where should the compiler construct the object? If NRVO takes effect, the object is constructed directly in the space provided by the caller.
However, what if the alternate path is taken? Then the object that actually should be constructed in this space is not rvo, but the unnamed temporary that should be returned. If NRVO had been applied, this space would already be taken by rvo, leading to a conflict.
That's why rvo has to be a separate variable in the function's own space. NRVO cannot be applied. RVO for the unnamed temporary can still be applied.