简体   繁体   中英

Postfix increment operator

I have a custom class MyInt, encapsulating a int m_nValue data. The postfix operator

MyInt operator++(int)  
{
  MyInt temp(*this);  
  ++(*this);  
  return temp; 
}

if the operator returns an object, then why i am not able to call postfix++ operator more than once like:

MyInt value(10);
value++;    // valid
value++++;  // Why is this invalid?? Cant it be interpreted as (value++)++

Why does value++++ gives an error lvalue required if i can call value.print() method defined in MyInt Class, then i should also be able to do value++++?

Wrong answer:

Because value++ is a temporary variable that holds the old value of value . You can't ++ it.

You also can't write 15++ ! It's similar. The former is a temporary variable, the later is a constant, none of which you can increment.

Correction: Since this answer got accepted, I am not going to change the original post, but since people will read it, I will post the correction here.

First off, I am not saying constants and temporary objects are the same concept. I was just trying to say temporary objects are not l-values, like constants are not, without actually using the word l-value.

About value++++ , it is not an error. I just tested it with my g++ 4.5 and it works fine. In other answers you can read:

From section 3.10.10 of the 2003 standard:

An lvalue for an object is necessary in order to modify the object except that an rvalue of class type can also be used to modify its referent under certain circumstances. [Example: a member function called for an object (9.3) can modify the object. ]

What is inherently wrong about what you are doing is this:

Let's say value holds 10 . The first value++ changes value to 11 but returns a temporary object containing 10 . Then you ++ it which changes the temporary value (that you never access) to 11 , but again returns a temporary object that contains 10 . So value++++ behaves exactly like value++ except it does some unnecessary work.

Actually, this should work :

#include <iostream>

struct MyInt {
    MyInt() : value(0) {}

    MyInt& operator++() {
        std::cout << "Inside MyInt::operator++()" << std::endl;
        ++value;
        return *this;
    }

    MyInt operator++(int)  
    {
      MyInt temp(*this);  
      ++(*this);  
      return temp; 
    }

    int value;
};

int main() {
    MyInt mi;

    std::cout << "Value before: " << mi.value << std::endl;
    mi++++;
    std::cout << "Value after: " << mi.value << std::endl;
}

This operator is basically just a normal member-function with fancy syntax, and as such you can invoke it on an rvalue. Note how, as Martinho explains in his comment, the effect is not the desired one, because the second increment operates on a temporary.

From section 3.10.10 of the 2003 standard:

An lvalue for an object is necessary in order to modify the object except that an rvalue of class type can also be used to modify its referent under certain circumstances. [Example: a member function called for an object (9.3) can modify the object. ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM