为什么++ x ++会出现编译错误?

时间:2015-05-13 15:29:52

标签: c++

我对后增量和预增量运算符的返回值感到困惑。是否返回r值或l值。

    #include<iostream>
    using namespace std;
    int main(){
        int a=10;
        cout<<++a++<<"\n";
    }

以下代码给出了编译错误。

error: lvalue required as increment operator

为什么会出错?

编译器如何评估表达式++a++

4 个答案:

答案 0 :(得分:7)

后增量表达式a++的结果是 rvalue ;在递增之前具有a值的临时值。作为 rvalue ,您可以使用其值,但不能修改它。具体来说,你不能像编译器那样应用预增量。

如果您要更改优先级以先执行预增量:

(++a)++

然后这将编译:预增量的结果是左值表示已被修改的对象。但是,这可能有不确定的行为;我不确定是否对这两个修改和值的各种用途进行了排序。

总结:不要试图编写带有多个副作用的棘手表达。

答案 1 :(得分:6)

从概念上讲,后缀++的优先级高于前缀++

首先计算a++。但这不是左值(因为它是a的先前值)。因此它不能预先递增。因此编译器输出。

更重要的是,整个表达式++a++的行为是未定义的,因为它们在表达式中没有排序点。

答案 2 :(得分:1)

只是为了它的价值(不是很多,IMO)如果你使问题a成为正确的类型,那么可以通过编译来定义行为。诀窍(在这种情况下,它是一个肮脏的,邪恶的技巧)是重载后修复增量运算符以返回左值:

class dirty_evil_trick {
    int val;
public:
    dirty_evil_trick() : val(0) {}

    // to demonstrate, I'll just make postfix increment act like prefix increment.
    dirty_evil_trick operator++(int) {  
        ++val;
        return *this;
    }

    dirty_evil_trick operator++() { 
        ++val;
        return *this;
    }

    operator int(){ return val; }
};

正如名称所暗示的,这是(至少在我看来)真正可怕的代码。我们已经使前缀和后缀增量运算符像前缀增量一样。因此,例如,如果我们按如下方式行使它:

int main(){ 
    dirty_evil_trick a;
    std::cout << ++a++;
}

...它应打印出2。并且,由于调用运算符重载函数强加了排序约束,我们应该能够依赖所有符合编译器的结果。

我将再次重复:这不是关于如何编写代码的建议。它实际上只是演示了您所获得的错误消息,以及如何编写所做的实际上可以正常工作的代码。

答案 3 :(得分:0)

首先,这是一种糟糕的编程风格。根据您的需要,您可以轻松地写下:

++a;
cout << a++ <<"\n";

a++;
cout << ++a <<"\n";

出现编译错误......

由于运算符优先级,++a++++(a++)相同。但是,a++计算为右值。不允许在rvalue上使用前缀增量运算符。这类似于使用++10,这是不合法的。