【问题标题】:lvalue required as increment operand error需要左值作为增量操作数错误
【发布时间】:2011-09-07 23:40:05
【问题描述】:
#include <stdio.h>

int main()
{
   int i = 10;
   printf("%d\n", ++(-i)); // <-- Error Here
}

++(-i) 有什么问题?请澄清。

【问题讨论】:

  • 即使它做一些合理的事情,我仍然请求你以一种对以后会阅读你的代码的人有意义的方式重写它

标签: c++ c operators lvalue rvalue


【解决方案1】:

-i 生成一个临时值,您不能将++ 应用于一个临时值(由右值表达式生成)。预增量++ 要求其操作数是左值,-i 不是左值,所以会出现错误。

【讨论】:

  • 我认为 SLaks 对此有正确的说法。它不是临时的,而是 r/lvalues。
  • @Nawaz:我不这么认为。你说这个答案没有说服力,因为你可以对 member operator++ 做类似的事情,这是一个完全不相关的问题。考虑struct A {}; A operator++( A &amp; ); ++A(); 哎呀......你不能在那里打电话给operator++。您更改了 问题(从内置预增量到成员预增量),然后声明此答案不能解决您的修改 问题。在向您解释了其中的区别之后,您无法接受自己犯了错误。我们都会犯错,这就是我们学习的方式。
  • @Xaade:你应该用++(-A())替换main,目前程序中没有临时的。而且我从来没有声称你不能有一个指代临时的左值表达式(有很多方法可以做到),但我仍然觉得同样的人一遍又一遍很有趣,并且没有真正理解这个问题仅仅因为他们可以编写一些似乎有效的类似(非等效)代码。如果对术语有一些建设性的批评,我会做得更好(大约 10 分钟前我刚刚在 Slaks 的回答中这样做了)
  • @Nawaz:您的确切评论是:我不认为这是一个正确的答案。您可以在临时应用 ++:ideone.com/cv9oI。这并不是说您发现 临时 具有误导性,而是您认为答案是错误的,因为通过将问题转换为 调用成员函数,您可以调用成员函数一个临时的。同样,使用该代码甚至不会暗示您正在谈论 temporaryrvalue 的区别,在这两种情况下,对象都是 temporaries 和表达式是 rvalue 表达式。
  • @Nawaz:说真的,一个坏了的时钟一天两次给出正确的时间。答案是(而且它的第一个版本)非常清楚。它使用-i 表达式,产生一个int 类型的temporary 和一个rvalue,它还说++ 需要一个lvalue。虽然它可能会更好——它可以避免提及临时,它可以指定++ 需要一个左值,除非它被重写为类成员函数,这超出了问题的范围。它可能会更好,但无论如何它都没有
【解决方案2】:

++ 运算符增加一个变量。 (或者,更准确地说,一个左值——可以出现在赋值表达式的l尾部的东西)

(-i) 不是变量,因此增加它没有意义。

【讨论】:

  • 我发现 variablelvalue 的相似性比替代的要好得多 可以出现在赋值表达式的左侧。我看到很多人争辩说你不能有一个产生 constant lvalue 的表达式,因为它不能用作赋值的左侧(鉴于const int&amp; foo();foo(); 是一个左值表达式,但您不允许 -- 由于其他原因 -- 分配给它)
【解决方案3】:

您不能增加没有身份的临时。您需要将其存储在某些东西中以增加它。 您可以将左值视为可以出现在表达式左侧的东西,但最终您需要将其视为具有标识但不能移动的东西(C++0x 术语)。这意味着它有一个身份、一个引用、一个对象,一个你想保留的东西。

(-i) 没有身份,所以没有什么可以引用它。没有什么可以引用它,就没有办法在其中存储一些东西。你不能引用 (-i),因此你不能增加它。

试试 i = -i + 1

#include <stdio.h>

int main()
{
   int i = 10;
   printf("%d\n", -i + 1); // <-- No Error Here
}

【讨论】:

    【解决方案4】:

    试试这个:

    #include <stdio.h>
    
    int main()
    {
       int i = 10;
       printf("%d\n", (++i) * -1);
    }
    

    【讨论】:

    • 应该是--i。 ++i*-1 是 -i-1,而--i*-1 是 (i-1)*-1=-i+1。
    猜你喜欢
    • 1970-01-01
    • 2020-10-06
    • 2021-05-11
    • 1970-01-01
    • 2022-01-02
    • 2012-10-01
    • 1970-01-01
    • 2014-04-07
    • 2011-12-20
    相关资源
    最近更新 更多