后缀自增运算符的常量返回类型

C++ Constant return type of suffix increment operator

本文关键字:常量 返回类型 运算符 后缀      更新时间:2023-10-16

在c++中,无论我在web中看到后缀增量操作符声明的例子,它总是被声明为

T& operator++(int);

,我相信这是后缀增量的正确语法,不是吗?

问题是,每当我声明后缀增量时,我都使用const关键字声明返回类型,因此它变得类似左值。

请参阅示例代码:

class AClass
{
    int foo;
public:
    AClass(void) : foo(0) {};
    // Suffix increment operator
    // Consider adding const to return type
    /* const */ AClass operator++(int)
    {
        AClass cp(*this);
        foo++;
        return cp;
    };
    // Prefix increment operator
    AClass& operator++()
    {
        foo++;
        return *this;
    };
};
int main(int argc, const char* args[])
{
    /* This code would fail to compile.
    int bar = 5;
    (bar++)++;
     */
    // Similarily, I would expect this to fail
    //   but it will succeed unless I use const return type.
    AClass a;
    (a++)++;
}
我从来没有遇到过这样一个const声明的操作符的问题,而且我知道它已经把我们的代码从一个笨拙的同事所犯的错误中拯救出来了。所以,我的问题是:
  1. 这种做法有什么缺点吗?这真的是一种好的做法吗?
  2. 后缀操作符(我指的是标准)的真正正确声明是什么?
  3. 如果这不是标准规定的方式,但已经是一个很好的实践,它不应该成为标准吗?

非常感谢你的回答!

后缀增量返回一个临时的,而不是一个引用(这意味着你的第一个签名是错误的):

T& operator++() // prefix
{
    this->increment();
    return *this;
}
T operator++(int) // suffix
{
    // Almost always, you'll have this code:
    T tmp(*this); ++(*this); return tmp;
}

有些人喜欢对后缀操作符的返回值进行const限定,以避免写出像

这样愚蠢的东西。
(a++).modify_me();

不修改a(它将modify_me应用于临时对象)。与

(++a).modify_me();

增加a,然后修改它。

我个人认为没有必要(因为你可能对modify_me的副作用感兴趣)。此外,在c++ 11中,您可能希望将上述临时对象绑定到(非const)右值引用。Const限定后缀操作符的返回类型禁用了这种可能性。

,我相信这是后缀增量的正确语法,不是吗它吗?

如果你说的"正确"是指"惯例",那就不是。如果您试图在整数上创建类似于后缀操作符的行为,那么它应该按值返回。

const T operator++(int);

这是因为它先复制,然后加1,然后返回副本。由于副本是本地的,因此您肯定不希望通过引用返回它。

可以接受或离开const,但必须返回值而不是引用。