使用NRV优化的函数应遵循哪些规则

时间:2011-05-07 00:27:14

标签: c++

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

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

1 个答案:

答案 0 :(得分:3)

如果您的意思是NRVO(命名返回值优化)而不是RVO(返回值优化),则必须在函数中命名对象。否则它只有资格获得RVO,而不是NRVO。所以有一个很好的理由称它为命名返回值优化。

查看以下示例:

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