【问题标题】:How to implement Postfix increment operator如何实现 Postfix 增量运算符
【发布时间】:2017-04-23 00:30:58
【问题描述】:

我学到了: 用户定义的后缀自增运算符应该返回一个 const 对象以表现得像一个基本的算术类型:

int i = 0;
i++ = 42; // error, i++ is pr-value
++i = 42; // ok, ++i is l-value

所以对于类 Widget 它应该被声明为

const Widget operator++(int);
...
Widget w1, w2;
w1++ = w2; // error, fine, same as i++ = 42

没有 const,它会编译。但是有了这个就不可能了 打电话给

void f(Widget&&);
f(w1++); // error, invalid initialization of Widget&& from expression const Widget

有什么遗憾,因为 w1++ 是一个 r-value 表达式,它的 constness 没有影响,因为它是一个临时的,不是吗?

现在,应该如何声明 operator++(int)? 感谢您的建议。

【问题讨论】:

标签: c++11 operator-overloading rvalue-reference


【解决方案1】:

Widget operator++(int); 是标准定义。

声明按值返回但也返回const 的函数,函数编写者试图限制函数使用者对该函数的操作。

就我个人而言,我从不这样做,这只是一个不必要的约束,并且会导致与您在此示例中显示的完全一样的问题。但其他人认为,为了获得关于w1++ = w2; 的编译器诊断,禁用f(w1++) 是值得的“代价”,这可能是一个逻辑错误。这真的是意见和编码风格的问题。

【讨论】:

    【解决方案2】:

    用户定义的后缀自增运算符应该返回一个 const 对象,使其表现得像一个基本的算术类型:

    在 C++11 中通常不建议返回 const-qualified 类类型。正如您所注意到的,它可以防止使用移动操作。为了表现得像基本算术类型,一种更简单的方法是禁用右值上的 = 运算符。

    struct S {
      S &operator=(const S &) & = default;
      S &operator=(S &&) & = default;
    };
    S f() { return {}; }
    int main() {
      S s;
      s = s; // okay
      s = f(); // okay
      f() = s; // error
    }
    

    有了这个,你可以声明Widget operator++(int);,拒绝w1++ = w2;,但允许f(w1++);

    【讨论】:

      猜你喜欢
      • 2011-05-18
      • 2011-05-19
      • 2020-08-15
      • 2021-05-21
      • 2011-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多