【问题标题】:Arithmetic operators parameter type算术运算符参数类型
【发布时间】:2016-12-07 17:24:40
【问题描述】:

经常说(例如这里cppreference)按值定义算术运算符的左侧(lhs)参数有助于优化链式操作。

X operator+( X         lhs
           , X const & rhs )

为确保我不会意外更改函数内的 lhs,我喜欢将我的值参数声明为 const。这是否会改变与所需优化相关的行为?

X operator+( X const   lhs
           , X const & rhs )

【问题讨论】:

  • 参见二元算术运算符部分
  • “为了确保我不会在函数中意外更改 lhs”, 这种方式违背了这种按值传递“优化”的目的,不会是吗?
  • 那么优化是我可以使用变量赋值(即返回lhs+=rhs)?
  • “优化”是“最简单的实现方式”的强词,但本质上是的。

标签: c++ operator-overloading


【解决方案1】:

++= 的形式实现时,通过复制来启用特定的习语:

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

另一方面,如果您通过const X& 引用lhs,您将不得不自己制作副本,像这样

inline X operator+(const X& lhs, const X& rhs) {
    X res(lhs); 
    res += rhs;
    return res;
}

或者构造一个新对象,像这样:

inline X operator+(const X& lhs, const X& rhs) {
    X res; 
    ... // Modify res to contain the sum of lhs and rhs
    return res;
}

如果您使用惯用方法,编译器可以通过复制一次来为您优化+ 链。当你这样做时,编译器会注意到

lhs + rhs1 + rhs2

lhs + rhs1 的结果是一个丢弃的副本,可以在构造(lhs + rhs1) + rhs2 时重复使用,而无需再次执行复制。

另一方面,如果您使用上述替代方法之一,编译器将需要为链中的每个操作制作一个副本。

【讨论】:

  • 感谢您如此充分地解决链接问题。在“Effective C++”中,Scott Meyers 投票赞成让二元算术运算符函数返回一个 const 值,以让编译器检测像 if( a + b = c) 这样的错误。这个 const 会以任何方式影响优化吗?
  • @DrPepperJo 我不认为它会,因为编译器“拥有”它优化出来的临时对象,所以它知道没有真正的分配正在进行(假设没有错误在优化器)。
猜你喜欢
  • 1970-01-01
  • 2015-09-03
  • 2011-09-30
  • 1970-01-01
  • 2011-02-24
  • 1970-01-01
  • 2010-10-19
  • 1970-01-01
  • 2022-01-07
相关资源
最近更新 更多