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

发布于 2024-12-11 18:43:09 字数 1080 浏览 7 评论 0原文

在 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. 如果这不是标准指定的方式,但已经是一种很好的做法,那么它不应该成为标准吗?

非常感谢您的回答!

In C++, wherever I see in web an example of suffix increment operator declaration, it is always declared as

T& operator++(int);

and I believe this is the correct syntax of a suffix increment, isn't it?

The issue is that, whenever I declare suffix increment, I declare return type with const keyword, so that it becomes lvalue-like.

Please see the example code:

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

I have never had problems about such a const-declared operator and I know it already saved our code from a bug made by a clumsy co-worker. So, my questions are:

  1. Are there any cons for such a practice? Is it a good practice indeed?
  2. What is the really correct declaration of suffix operator (I mean standards)?
  3. If this is not how the standard specifies but is already a good practice, shouldn't it become a standard?

Thanks a lot for your answers!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

笑脸一如从前 2024-12-18 18:43:09

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

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

Suffix increment returns a temporary, not a reference (this means your first signature is wrong):

T& operator++() // prefix
{
    this->increment();
    return *this;
}

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

Some people like to const-qualify the return value of the suffix operator to avoid writing stupid things like

(a++).modify_me();

which doesn't modify a (it applies modify_me to a temporary object). Contrast with

(++a).modify_me();

which increments a and then modifies it.

Personally, I don't think it is necessary (since you may be interested in the side effects of modify_me). Moreover, in C++11, you may want to bind said temporary to a (non const) rvalue reference. Const qualifying the return type of suffix operators disables this possibility.

小巷里的女流氓 2024-12-18 18:43:09

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

如果“正确”指的是“常见做法”,那么就不行。如果您尝试创建类似于整数后缀运算符的行为,那么它应该按值返回。

const T operator++(int);

这是因为它创建一个副本,然后递增,然后返回该副本。由于副本是本地的,因此您绝对不想通过引用返回它。

您可以使用或保留 const,但按值返回而不是按引用返回是至关重要的。

and I believe this is the correct syntax of a suffix increment, isn't
it?

If by "correct", you mean "common practice", then no. If you're trying to create behavior analagous to the postfix operator on integers, then it should return by value.

const T operator++(int);

This is because it makes a copy, then increments, then returns the copy. Since the copy is local, you definitely don't want to return it by reference.

The const you can take or leave, but the return by value rather than reference is essential.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文