引入新变量是否会破坏返回值优化?

4
我们都知道,
Foo returnAFoo()
{
    return Foo();
}

将使用返回值优化编译,即使Foo的复制构造函数具有副作用,也不会进行值复制。但是会

Foo returnAFoo()
{
    Foo f = Foo();
    return f;
}

也是吗?第二个结构在调试时可能会有帮助。但我这样做是不是放弃了一个重要的优化?也许我需要编写一个明确的移动构造函数?


1
请注意,有一种特定的返回值优化变体称为命名返回值优化(NRVO)。它有时比“普通”RVO更难,但通常编译器可以处理。两者都与移动对象完全不同。如果您有显式的复制构造函数/赋值运算符,则还需要显式定义移动构造函数/赋值运算符。 - BoBTFish
@BoBTFish:请将其作为答案发布,我会接受它。 - P45 Imminent
1
http://cpp.sh/9yvs - Humam Helfawi
@P45 我没精力(或者说应该做的工作很多)去举例,加上参考等等。别担心,很快就会有其他人来完成它。(不要因为只有一个答案而接受不完整的答案)。 - BoBTFish
@BoBTFish,即使没有移动操作,复制省略也可以正常工作。你能澄清一下吗? - Angew is no longer proud of SO
1个回答

7
没有。在这种情况下仍然可以应用复制省略。在这种特定情况下,它被称为NRVO(命名返回值优化)。您不需要移动构造函数来执行复制省略;自C++98/03以来,我们就已经有了复制构造函数的标准。
为了最大化使用复制省略的机会,您应确保以下两点之一:所有代码路径都返回相同的对象(NRVO),或者所有代码路径都返回临时对象(RVO)。
如果您在同一个函数中混合使用NRVO和RVO,则很难应用该优化。
演示NRVO的示例代码

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接