如果您指的是 NRVO(命名返回值优化)而不是 RVO(返回值优化),那么该对象必须在函数内部命名。否则,它只能获得 RVO,而不能获得 NRVO。所以有一个很好的理由来称呼它Named返回值优化。
查看以下示例:
RVO:
BigObject foo(int x, int y)
{
// Returned BigObject is created ad-hoc, and has no local 'name'.
return BigObject(x, y);
}
void bar()
{
BigObject obj = foo(4, 6);
}
将由优化编译器翻译为以下伪代码:
void foo(int x, int y, BigObject& ret)
{
ret._constructor_(x, y);
}
void bar()
{
BigObject obj; // Allocate obj on the stack, but don't construct it just yet!
foo(4, 6, obj); // Now obj is constructed by foo()
}
NRVO:
BigObject foo(int x, int y, int z)
{
// Returned BigObject has a local 'name' in foo(), which is obj.
BigObject obj(x, y);
// Do something with obj
obj.setZ(z);
return obj;
}
void bar()
{
BigObject obj = foo(4, 6, 7);
}
将由优化编译器翻译为以下伪代码:
void foo(int x, int y, int z, BigObject& ret)
{
ret._constructor_(x, y);
// Do something with ret
ret.setZ(z);
}
void bar()
{
BigObject obj; // Allocate obj on the stack, but don't construct it just yet!
foo(4, 6, 7, obj); // Now obj is constructed by foo()
}
请注意,优化是否实际发生很大程度上取决于编译器。某些编译器(例如非常旧的编译器)根本不会执行 RVO 或 NRVO,而其他编译器可能对此优化有不同的限制。以下是 MSVC 对 NRVO 施加的约束的描述:http://msdn.microsoft.com/en-us/library/ms364057(v=vs.80).aspx#nrvo_cpp05_topic3 http://msdn.microsoft.com/en-us/library/ms364057(v=vs.80).aspx#nrvo_cpp05_topic3