C++ 中重载算术运算符的最佳签名是什么?

发布于 2024-07-06 02:10:29 字数 375 浏览 10 评论 0 原文

我假设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;
}

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

两个参数的类型不同似乎有点尴尬,但是第二种形式有什么问题吗? 有理由选择其中一种而不是另一种吗?

I had assumed that the canonical form for operator+, assuming the existence of an overloaded operator+= member function, was like this:

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

But it was pointed out to me that this would also work:

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

In essence, this form transfers creation of the temporary from the body of the implementation to the function call.

It seems a little awkward to have different types for the two parameters, but is there anything wrong with the second form? Is there a reason to prefer one over the other?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

风透绣罗衣 2024-07-13 02:10:29

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

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

I'm not sure if there is much difference in the generated code for either.

Between these two, I would (personally) prefer the first form since it better conveys the intention. This is with respect to both your reuse of the += operator and the idiom of passing templatized types by const&.

南风起 2024-07-13 02:10:29

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

研究返回值优化主题,例如此链接作为快速示例:http://www.cs.cmu.edu/~gilpin/c++/performance.html

With the edited question, the first form would be preferred. The compiler will more likely optimize the return value (you could verify this by placing a breakpoint in the constructor for T). The first form also takes both parameters as const, which would be more desirable.

Research on the topic of return value optimization, such as this link as a quick example: http://www.cs.cmu.edu/~gilpin/c++/performance.html

毅然前行 2024-07-13 02:10:29

为了可读性,我更喜欢第一种形式。

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

I would prefer the first form for readability.

I had to think twice before I saw that the first parameter was being copied in. I was not expecting that. Therefore as both versions are probably just as efficient I would pick them one that is easier to read.

我最亲爱的 2024-07-13 02:10:29
const T operator+(const T& lhs, const T& rhs)
{
    return T(lhs)+=rhs;
}

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

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

why not this if you want the terseness?

泪眸﹌ 2024-07-13 02:10:29

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

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

My first thought is that the second version might be infinitessimally faster than the first, because no reference is pushed on the stack as an argument. However, this would be very compiler-dependant, and depends for instance on whether the compiler performs Named Return Value Optimization or not.

Anyway, in case of any doubt, never choose for a very small performance gain that might not even exist and you more than likely won't need -- choose the clearest version, which is the first.

过度放纵 2024-07-13 02:10:29

事实上,第二种是首选。 正如 C++ 标准中所述,

3.7.2/2:自动存储时长

如果一个命名的自动对象有
初始化或析构函数
副作用,不应该
在其块结束之前被销毁,
也不应将其作为
优化,即使看起来是
未使用,除了类对象或
它的副本可以被消除为
12.8 中指定。

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

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

Actually, the second is preferred. As stated in the c++ standard,

3.7.2/2: Automatic storage duration

If a named automatic object has
initialization or a destructor with
side effects, it shall not be
destroyed before the end of its block,
nor shall it be eliminated as an
optimization even if it appears to be
unused, except that a class object or
its copy may be eliminated as
specified in 12.8.

That is, because an unnamed temporary object is created using a copy constructor, the compiler may not use the return value optimization. For the second case, however, the unnamed return value optimization is allowed. Note that if your compiler implements named return value optimization, the best code is

const T operator+(const T& lhs, const T& rhs)
{
    T temp(lhs);
    temp +=rhs;
    return temp;
}
天煞孤星 2024-07-13 02:10:29

我认为,如果你将它们都内联(我会这样做,因为它们只是转发函数,并且可能operator+=()函数是外线的),你会得到几乎无法区分的代码生成。 也就是说,第一个更为规范。 第二个版本不必要地“可爱”。

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".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文