【问题标题】:Confusion about `const` in compound assignment对复合赋值中的“const”感到困惑
【发布时间】:2020-09-18 04:50:00
【问题描述】:

operator+=canonical implementation 将 RHS 作为 const 引用传递:

X& operator+=(const X& rhs)

然而,在

x += x;

RHS 修改。这会调用 UB 吗?

【问题讨论】:

  • 为什么你认为这里有UB? x 是可修改的。 rhs 没有,但没有被修改。
  • rhs是怎么修改的?按照你的思路,int a = 5; int const& ar = a; a = 6;算不算修改ar
  • 骗子似乎不是正确的:X += X 是 UB,因为关于副作用和不确定顺序的规则。 rhs 是只读的或不可变的这一事实在这里不起作用
  • @Christophe - 该规则仅适用于内置运算符。重载运算符是函数调用
  • const 引用并不意味着它所引用的对象是 const 或不能更改。

标签: c++ operator-overloading language-lawyer const-correctness


【解决方案1】:

来自dcl.type.cv

一个指向 cv 限定类型的指针或引用实际上不需要指向或引用一个 cv 限定对象,但它被当作是这样处理; const 限定的访问路径不能用于修改对象,即使引用的对象是非 const 对象并且可以通过其他访问路径进行修改

引用 rhs 是 const 限定的,因此不能用于修改它所引用的对象。

但是,被引用的对象,即x,是非常量的,因此x本身可以通过其他访问路径进行修改,例如在operator+=的定义中。

因此,此代码示例中的行为已得到很好的定义。

【讨论】:

    【解决方案2】:

    const 表示引用是对 const 的引用,对 const 的引用可以绑定到非 const 对象。将对 const 的引用绑定到非 const 对象不会使对象本身成为 const。它只是意味着你不能通过对 const 的引用来修改对象,如果对象不是 const 则可以通过其他方式进行修改。

    在这种情况下,引用是对const的引用,但是引用的对象不是const,所以修改对象就可以了。

    【讨论】:

      【解决方案3】:

      让我提供另一种思考方式。

      IIRC,const 仅对调试可见。这意味着您无法通过这种方式修改事物,即此名称(reference)。当您编译程序时,编译器会在检查您以正确的方式完成所有操作后将它们删除。

      【讨论】:

        猜你喜欢
        • 2017-11-11
        • 2018-02-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-18
        • 2015-12-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多