什么是最好的"在现代C ++中重载算术运算符的方法?

时间:2016-05-30 04:45:31

标签: c++11 operator-overloading move-semantics arithmetic-expressions

我想实现一种类似数字的" C ++中的数学对象(比如组或环中的元素)。我确信我不是唯一一个处理这个问题的人,因此可能会有大量关于什么是最好的"重载算术运算符的方法。但是,我找不到满意的答案(虽然我可能懒得去搜索更多)。

让我们说我想让操作员超载" +"对于A班 问题是,我可以想到有太多不同的重载:

  1. operator +(const A& x,const A& y)
  2. 操作员+(const A& x,A&& y)
  3. 操作员+(A&& x,const A& y)
  4. 操作员+(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)&&
  9. 第一个问题。所有这些重载都必须使A的实例上的操作尽可能高效,而且就像原始类型一样#34;尽可能?我认为"普通" case,rvalue-qualified A :: operator + =不需要(或不应该)重载。这样对吗?我认为所有1-4都是必要的。例如,对于案例3,由于移动了x,我们不需要分配新的空间来保存返回值,我们可以安全地重用为x保留的分配存储。是不是?

    第二个问题。我认为所有这些重载可能会分享大多数此类情况的代码。如何在不牺牲性能等的情况下最小化代码重复?有没有特殊的技巧/成语呢? 如果存在,我更喜欢通用和可扩展的方法。

1 个答案:

答案 0 :(得分:4)

不可能给出最一般的答案,因为选择" best"方式将涉及了解有关操作的细节。

例如,最常见的模式(我在下面给出)对于矩阵乘法来说并不是那么好,因为在这种情况下,最简单的方法是声明一个从零开始并读取两个参数的第三个矩阵。此外,您可能希望使用延迟评估,在这种情况下,这些都不适用。

我建议您确保代码为所有案例提供正确的答案,并且一旦您的程序正常运行并且您有更多的语言经验,您就可以担心微优化。

对于实现+的最有效方法是修改其中一个参数的类,以下两种情况涵盖所有用途,具有强异常保证:

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

有关上述代码的作用及原因的更多说明,请参阅http://example.com/assets/css/magazine.min.css

在C ++ 03中,使用A const& x而不是A x并没有多大区别,但在C ++ 11中,对于第一个参数的情况,这稍微更优化一些是一个右值,因为现在可以从第一个参数中窃取资源。

关于在operator+=上使用ref-qualifiers的决定。对&&&的单独重载没有任何好处。如果您已经看到人们使用&,那么基本原理也不是重载,而是为了尝试在右值上使用+=而给出编译错误;理由是这可能是一个错误。

相关问题