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

时间:2011-10-26 15:41:10

标签: c++ coding-style operator-keyword increment

在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声明的运算符的问题,我知道它已经从一个笨拙的同事的bug中保存了我们的代码。所以,我的问题是:

  1. 这种做法有没有缺点?这确实是一种好习惯吗?
  2. 什么是后缀运算符的真正正确的声明(我的意思是标准)?
  3. 如果这不是标准规定的方式,但已经是一个好的做法,那么它不应该成为标准吗?
  4. 非常感谢您的回答!

2 个答案:

答案 0 :(得分:6)

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

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限定后缀运算符的返回类型会禁用这种可能性。

答案 1 :(得分:1)

  

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

如果“正确”,你的意思是“普通的做法”,那么没有。如果您尝试在整数上创建与postfix运算符类似的行为,那么它应该按值返回。

const T operator++(int);

这是因为它制作副本,然后递增,然后返回副本。由于副本是本地的,因此您绝对不希望通过引用返回它。

你可以采取或离开的常数,但是按价值而不是参考的回报是必不可少的。