什么是“最佳"?现代C ++中重载算术运算符的方法? [英] What is the "best" way to overload arithmetic operators in modern C++?

查看:113
本文介绍了什么是“最佳"?现代C ++中重载算术运算符的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在C ++中实现一种类似于数字"的数学对象(例如,组或环中的元素).我确信我不是唯一一个处理此问题的人,因此可能有很多关于什么是重载算术运算符的最佳"方法的讨论.但是,我找不到满意的答案(尽管也许我太懒了以至于无法谷歌搜索更多内容.)

I want to implement a kind of "number-like" mathematical objects (say, elements in a group or a ring) in C++. I'm sure that I'm not the only one dealing with this problem, so there may be abundant amount of discussions about what is the "best" way of overloading arithmetic operators. However, I couldn't find satisfactory answers (although maybe I was too lazy to googling more).

假设我要为A类重载运算符"+". 问题是,我能想到太多不同的重载:

Let's say I want to overload the operator "+" for a class A. The problem is, there are too many different overloads I can think of:

  1. operator +(const A& x,const A& y)
  2. operator +(const A& x,A&&y)
  3. operator +(A&& x,const A& y)
  4. operator +(A& x,A& y)
  5. A :: operator + =(const A& y)&
  6. A :: operator + =(const A& y)&&
  7. A :: operator + =(A& y)&
  8. A :: operator + =(A& y)&&

第一个问题.为了使对A实例的操作尽可能高效且尽可能像原始类型一样",是否需要所有这些重载?我认为在普通"情况下,不需要(或不应)重载右值限定的A :: operator + =.这样对吗?我认为所有1-4都是必要的.例如,对于情况3,由于x被移动,我们不需要分配新的空间来保存返回值,并且我们可以安全地重用为x保留的分配存储.是吗?

First question. Do all of these overloads necessary to make operations on instances of A as efficient as, and as much as "being like primitive types" as possible? I think for "ordinary" cases, rvalue-qualified A::operator+= need not (or should not) be overloaded. Is it right? I think all of 1-4 are necessary. For example, for the case 3, since x is being moved, we do not need to allocate a new space to hold the return value, and we can safely reuse the allocation storage reserved for x. Is it right?

第二个问题.我认为在大多数情况下,所有这些重载都可能共享许多代码.如何在不牺牲性能等的情况下最小化代码重复?是否有任何特殊的技巧/习惯来做到这一点? 我更喜欢通用和可扩展的方法(如果存在).

Second question. I think all of these overloads may share a lot of codes for most of this kind of cases. How can I minimize the code duplication without sacrificing performance/etc.? Is there any special techniques/idioms to do this? I prefer general and extensible methods, if exist.

推荐答案

不可能给出最笼统的答案,因为选择最佳"方式将涉及对操作细节的理解.

It's not possible to give a most-general answer, because choosing the "best" way will involve an appreciation of details about the operation.

例如,最常见的模式(我在下面给出)对矩阵乘法不太好,因为在那种情况下,最简单的方法是声明第一个从零开始并读取两个参数的矩阵.另外,在这种情况下,您可能都想使用惰性评估.

For example the most common pattern (which I give below) is not so good for Matrix Multiplication, because in that case it is simplest to declare a third matrix that starts off zeroed and reads the two arguments. Also you may want to use lazy evaluation in which case none of this applies.

我建议确保您的代码在所有情况下都能给出正确的答案,一旦程序运行并且您对语言有更多的经验,以后就可以担心微优化.

I would recommend making sure that your code gives the correct answers for all cases, and you can worry about micro-optimization later once your program works and once you have more experience in the language.

对于实现+的最有效方法是修改参数之一的类,则以下两种情况涵盖了所有用法,并具有强烈​​的异常保证:

For a class where the most efficient way to implement + is to modify one of the arguments, then the following two cases cover all uses, with the strong exception guarantee:

A& A::operator+=(A const &y) { /* modify *this using y */ ; return *this; }
A operator+ ( A x, A const& y ) { x += y; return x; }

有关上述代码的作用以及原因的更多说明,请参见运算符重载大线程.

For more explanation about what the above code does and why, see the operator overloading megathread.

在C ++ 03中,使用A const& x代替A x并没有多大区别,但是在C ++ 11中,对于第一个参数是右值的情况,这稍为最佳,因为资源现在可以从第一个参数中偷走了.

In C++03 it didn't make much difference to use A const& x instead of A x, but in C++11 this is slightly more optimal for the case where the first argument is an rvalue, because resources can now be stolen from the first argument.

关于在operator+=上使用ref限定符的决定. &&&单独重载没有任何好处.如果您看到人们在使用&,则其理由不是也要重载,而是要为在右值上使用+=的尝试给出编译错误;否则,可能会出现编译错误.理由是这很可能是错误的.

Regarding the decision to use ref-qualifiers on operator+=. There is no benefit to overloading separate for & and &&. If you have seen people using &, the rationale is not to also overload, but to give a compile error for the attempt to use += on an rvalue; with the rationale being that that's likely to be a mistake.

这篇关于什么是“最佳"?现代C ++中重载算术运算符的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆