后自增和预自增运算符的优先级

发布于 12-07 07:27 字数 1273 浏览 0 评论 0原文

有代码:

#include <iostream>

class Int {
public:
    Int() : x(0) {}
    Int(int x_) : x(x_) {}
    Int& operator=(const Int& b) {
        std::cout << "= from " << x << " = " << b.x << std::endl;
        x = b.x;
    }
    Int& operator+=(const Int& b) {
        std::cout << "+= from " << x << " + " << b.x << std::endl;
        x += b.x;
        return *this;
    }
    Int& operator++() {
        std::cout << "++ prefix " << x << std::endl;
        ++x;
        return *this;
    }
    Int operator++(int) {
        std::cout << "++ postfix " << x << std::endl;
        Int result(*this);
        ++x;
        return result;
    }
private:
    int x;

};

Int operator+(const Int& a, const Int& b) {
    std::cout << "operator+" << std::endl;
    Int result(a);
    result += b;
    return result;
}

int main() {
    Int a(2), b(3), c(4), d;
    d = ++a + b++ + ++c;
    return 0;
}

结果:

++ prefix 4
++ postfix 3
++ prefix 2
operator+
+= from 3 + 3
operator+
+= from 6 + 5
= from 0 = 11

为什么后缀运算符不在前缀运算符(++前缀4)之前执行,尽管后缀运算符的优先级高于前缀运算符?

这是由 g++ 编译的。

There is code:

#include <iostream>

class Int {
public:
    Int() : x(0) {}
    Int(int x_) : x(x_) {}
    Int& operator=(const Int& b) {
        std::cout << "= from " << x << " = " << b.x << std::endl;
        x = b.x;
    }
    Int& operator+=(const Int& b) {
        std::cout << "+= from " << x << " + " << b.x << std::endl;
        x += b.x;
        return *this;
    }
    Int& operator++() {
        std::cout << "++ prefix " << x << std::endl;
        ++x;
        return *this;
    }
    Int operator++(int) {
        std::cout << "++ postfix " << x << std::endl;
        Int result(*this);
        ++x;
        return result;
    }
private:
    int x;

};

Int operator+(const Int& a, const Int& b) {
    std::cout << "operator+" << std::endl;
    Int result(a);
    result += b;
    return result;
}

int main() {
    Int a(2), b(3), c(4), d;
    d = ++a + b++ + ++c;
    return 0;
}

Result:

++ prefix 4
++ postfix 3
++ prefix 2
operator+
+= from 3 + 3
operator+
+= from 6 + 5
= from 0 = 11

Why postfix operator isn't executed before prefix operator (++ prefix 4) altough priority of postfix operator is higher than prefix operator?

This was compiled by g++.

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

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

发布评论

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

评论(2

旧梦荧光笔2024-12-14 07:27:46

不同操作数的求值顺序未指定,这意味着编译器可以自由地重新排序 ++ab++++c< /code> 子表达式,随意。在此示例中,运算符的优先级实际上并没有任何影响。

如果您尝试编写 ++i++ (其中 iint),它确实会产生效果,它将被分组为 + +(i++) 并且它将无法编译,因为子表达式 i++ 是右值,而前缀增量需要左值。如果优先级颠倒,则该表达式将编译(并导致未定义的行为)

The order of evaluation of the different operands is unspecified which means that the compiler is free to reorder the evaluation of the ++a, b++ and ++c subexpressions as it pleases. The precedence of the operators does not really have any impact in that example.

It does have an effect if you try to write ++i++ (where i is an int) which will be grouped as ++(i++) and it will fail to compile as the subexpression i++ is an rvalue and prefix increment requires an lvalue. If the precedence was reversed, then that expression would compile (and cause Undefined Behavior)

星星的軌跡2024-12-14 07:27:46

Postfix ++ 在表达式 ++a + b++ + ++c 中具有最高优先级,但 + 具有最低优先级并被保留联想的。该表达式可以等效地写为 (++a) + (b++) + (++c) (每个 ++ 是不同子表达式的一部分),这解释了为什么首先评估++a。考虑遍历/评估相应的解析树,评估的顺序就变得显而易见:

           E
         / | \
        /  |  E
       /   |  | \
      E    +  ++  c
    / | \
   /  |  \
  E   +   E
 / \     / \
++  a   b  ++

Postfix ++ has the highest precedence in the expression ++a + b++ + ++c, but + has the lowest precedence and is left associative. This expression can be equivalently written as (++a) + (b++) + (++c) (each ++ is part of a different subexpressions) which explains why ++a is evaluated first. Consider traversing/evaluating the corresponding parse tree and it becomes obvious what the order of evaluation:

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