在没有返回值优化的情况下将两个对象添加到一起时会创建多少个临时对象?

use*_*738 6 c++ effective-c++ operator-keyword return-value-optimization copy-elision

在阅读Scott Meyers所着的"更有效的C++"一书的第20和22项后,我决定提出这个问题.

假设你写了一个代表有理数的类:

class Rational
{
public:
    Rational(int numerator = 0, int denominator = 1);

    int numerator() const;
    int denominator() const;

    Rational& operator+=(const Rational& rhs); // Does not create any temporary objects
    ...
};
Run Code Online (Sandbox Code Playgroud)

现在让我们说你决定operator+使用operator+=:

const Rational operator+(const Rational& lhs, const Rational& rhs)
{
    return Rational(lhs) += rhs;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:如果禁用返回值优化,将创建多少个临时变量operator+

Rational result, a, b;
...
result = a + b;
Run Code Online (Sandbox Code Playgroud)

我相信会创建2个临时值:一个Rational(lhs)是在body体内执行的operator+,另一个operator+是在返回的值是通过复制第一个临时值创建的.

当Scott提出这个操作时,我的困惑出现了:

Rational result, a, b, c, d;
...
result = a + b + c + d;
Run Code Online (Sandbox Code Playgroud)

并写道:"可能使用3个临时对象,每次调用一个operator+".我相信如果禁用返回值优化,上面的操作将使用6个临时对象(每次调用2个operator+),而如果启用,则上面的操作根本不使用临时值.斯科特是如何得出他的结果的?我认为这样做的唯一方法是部分应用返回值优化.

son*_*yao 3

我认为你考虑太多了,尤其是优化的细节。

对于result = a + b + c + d;,作者只想说明将创建 3 个临时变量,第一个用于 的结果a + b,第二个用于 的结果temporary#1 + c,第三个用于temporary#2 + d然后分配给result。此后,3 个临时对象被销毁。所有临时结果仅用作中间结果。

另一方面,一些习惯用法(例如表达式模板)可以通过消除临时值直接获得最终结果。