函数使用NRV优化需要遵循哪些规则?

What rules to follow for a function to use NRV optimization

本文关键字:规则 NRV 优化 函数      更新时间:2023-10-16

我应该遵循什么规则或技巧来使函数在函数中使用NRV(命名返回值)优化?我从不同的地方吸收了这些技巧,但不知道我的理解是否正确:

    要返回的对象不应该在函数中有任何名称(那么为什么它被称为NAMED返回值优化!!)
  1. 返回语句应该有一个用圆括号包围的对象
  2. 要返回的
  3. 对象应该具有显式和内联的复制构造函数

如果您指的是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