如何实现Postfix自增运算符

How to implement Postfix increment operator

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

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

所以对于 class 小部件,它应该声明为

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

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

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

遗憾的是,因为 w1++ 是右值表达式,它的常量性没有影响,因为它是临时的,不是吗?

现在,应该如何声明operator++(int)? 谢谢指教

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

按值 return 和 return const 声明函数,函数编写者试图限制函数使用者对函数的操作。

就我个人而言,我从不这样做,这只是一个不必要的约束,会导致与您在此示例中显示的问题完全相同的问题。但是其他人认为 "price" 不允许 f(w1++) 是值得的,以便获得关于 w1++ = w2; 的编译器诊断,这可能是一个逻辑错误。这真的是一个观点和编码风格的问题。

A user defined postfix increment operator should return a const object to behave like a fundamental arithmetic type:

在 C++11 中通常不推荐返回 const 限定的 class 类型。正如您所注意到的,它会阻止使用移动操作。要表现得像基本算术类型,一种更简单的方法是禁用右值上的 = 运算符。

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++);