post和pre Incrementation运算符的优先级

时间:2011-09-28 15:28:31

标签: c++ operators

有代码:

#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)之前没有执行postfix运算符,而后缀运算符的优先级高于前缀运算符?

这是由g ++编译的。

2 个答案:

答案 0 :(得分:4)

未指定不同操作数的评估顺序,这意味着编译器可以随意对++ab++++c子表达式的评估进行重新排序。在该示例中,运算符的优先级实际上没有任何影响。

如果您尝试编写++i++(其中iint),它将被归为++(i++)并且无法编译为子表达式i++是一个rvalue,前缀增量需要一个左值。如果优先级被颠倒,那么该表达式将编译(并导致未定义的行为)

答案 1 :(得分:0)

Postfix ++在表达式++a + b++ + ++c中具有最高优先级,但+具有最低优先级并且是左关联的。此表达式可以等效地写为(++a) + (b++) + (++c)(每个++是不同子表达式的一部分),这解释了为什么首先评估++a。考虑遍历/评估相应的解析树,很明显评估的顺序是什么:

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