1

我假设 operator+ 的规范形式,假设存在重载的 operator+= 成员函数,是这样的:

const T operator+(const T& lhs, const T& rhs)
{
    return T(lhs) +=rhs;
}

但有人向我指出,这也行得通:

const T operator+ (T lhs, const T& rhs)
{
    return lhs+=rhs;
}

本质上,这种形式将临时的创建从实现主体转移到函数调用。

两个参数有不同的类型似乎有点别扭,但是第二种形式有什么问题吗?有理由偏爱其中一个吗?

4

7 回答 7

4

我不确定两者生成的代码是否有很大差异。

在这两者之间,我(个人)更喜欢第一种形式,因为它更好地传达了意图。这是关于您对 += 运算符的重用和通过 const& 传递模板化类型的习惯用法。

于 2008-09-23T01:43:26.897 回答
2

对于已编辑的问题,首选第一种形式。编译器更有可能优化返回值(您可以通过在 T 的构造函数中放置断点来验证这一点)。第一种形式也将两个参数都作为 const,这将是更可取的。

返回值优化课题的研究,比如这个链接作为一个简单的例子:http ://www.cs.cmu.edu/~gilpin/c++/performance.html

于 2008-09-23T01:39:58.807 回答
2

为了便于阅读,我更喜欢第一种形式。

在我看到第一个参数被复制之前,我不得不三思而后行。我没想到会这样。因此,由于这两个版本可能都一样有效,我会选择一个更容易阅读的版本。

于 2008-09-23T02:15:12.890 回答
1
const T operator+(const T& lhs, const T& rhs)
{
    return T(lhs)+=rhs;
}

如果您想要简洁,为什么不这样做呢?

于 2008-09-23T04:02:53.537 回答
1

我的第一个想法是第二个版本可能比第一个版本快得多,因为没有将引用作为参数推送到堆栈上。但是,这将非常依赖于编译器,并且取决于例如编译器是否执行命名返回值优化。

无论如何,如果有任何疑问,永远不要选择一个非常小的性能提升,甚至可能不存在并且您很可能不需要 - 选择最清晰的版本,这是第一个。

于 2008-09-23T07:10:01.153 回答
0

实际上,第二个是首选。如 c++ 标准中所述,

3.7.2/2:自动存储时长

如果命名的自动对象具有初始化或具有副作用的析构函数,则不应在其块结束之前将其销毁,即使看起来未使用,也不应作为优化消除,除非类对象或其副本可以按照 12.8 中的规定消除。

也就是说,由于使用复制构造函数创建了一个未命名的临时对象,编译器可能不会使用返回值优化。然而,对于第二种情况,未命名的返回值优化是允许的。请注意,如果您的编译器实现了命名返回值优化,那么最好的代码是

const T operator+(const T& lhs, const T& rhs)
{
    T temp(lhs);
    temp +=rhs;
    return temp;
}
于 2008-11-02T01:09:16.730 回答
0

I think that if you inlined them both (I would since they're just forwarding functions, and presumably the operator+=() function is out-of-line), you'd get near indistinguishable code generation. That said, the first is more canonical. The second version is needlessly "cute".

于 2008-11-02T01:20:44.477 回答