如何实现Postfix增量运算符

时间:2016-12-07 21:52:44

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

我了解到: 用户定义的后缀增量运算符应返回一个const对象,其行为类似于基本算术类型:

>>> primes = set(primes)
>>> all(any(n - p in primes for p in primes) for n in evens)

因此对于类Widget,它应该被声明为

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

没有const,它会编译。但有了这个,它是不可能的, 致电

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

什么是可怜的,因为w1 ++是一个r值表达式,它的常量没有影响,因为它是暂时的,不是吗?

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

2 个答案:

答案 0 :(得分:2)

  

用户定义的后缀增量运算符应返回一个const对象,其行为类似于基本算术类型:

在C ++ 11中通常不建议返回const - 限定类类型。正如您所注意到的,它阻止了移动操作的使用。为了像基本算术类型一样,更简单的方法是禁用rvalues上的=运算符。

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

答案 1 :(得分:0)

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

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

就我个人而言,我从不这样做,这只是一个不必要的约束,并导致问题,就像你在这个例子中所示。但其他人认为,为了让编译器诊断出f(w1++)可能是一个逻辑错误而禁止w1++ = w2;的“价格”是值得的。这真是一个意见和编码风格的问题。