Why myClassObj++++ doesn't incur a compile error : '++' needs l-value just as buildin type do?

扶醉桌前 提交于 2019-12-06 23:33:31

问题


Why myint++++ compiles fine with VS2008 compiler and gcc 3.42 compiler ?? I was expecting compiler say need lvalue, example see below.

struct MyInt
{
    MyInt(int i):m_i(i){}

    MyInt& operator++() //return reference,  return a lvalue
    {
        m_i += 1;
        return *this;
    }

    //operator++ need it's operand to be a modifiable lvalue
    MyInt operator++(int)//return a copy,  return a rvalue
    {
        MyInt tem(*this);
        ++(*this);
        return tem;
    }

    int     m_i;
};

int main()
{
    //control: the buildin type int
    int i(0);
    ++++i;  //compile ok
    //i++++; //compile error :'++' needs l-value, this is expected

    //compare 
    MyInt  myint(1);
    ++++myint;//compile ok
    myint++++;//expecting compiler say need lvalue , but compiled fine !? why ??
}

回答1:


No, overloaded operators are not operators - they're functions. So GCC is correct to accept that.

myobj++++; is equivalent to myobj.operator++(0).operator++(0); Caling a member function (including overloaded operator) on a temprorary object of class type is allowed.




回答2:


Because for user-defined types, operator overloads are literally just function calls, and so obey the semantics of function calls.




回答3:


If you want to emulate the built-in behaviour there’s actually a very simple solution: make the return value const:

MyInt const operator++(int) { … }

A few years back there was a debate over whether user-defined operators should exactly model the built-in behaviour. I’m not sure which school of thought currently has the upper hand, but making the return type of operator++(int) const was a way of achieving this.




回答4:


In the end, MyInt::operator++(int) is just another method. The same rules apply. Since you can call methods on rvalues, you can call operator++(int) on rvalues.




回答5:


myint++ returns something similar to MyInt(2). So, it's similar to doing MyInt(2)++. A temporary class is created in the operator++ function and you're incrementing the temporary class. After it's returned, it's deleted as soon as the next statement finishes (here, it's second ++ operator).




回答6:


The issue is that the requirements of the postincrement operator for integral types and for user defined types are different. In particular a user defined postincrement operator implemented as a member function allow the use of rvalues.

If you had implemented the operator as a free function:

MyInt operator++(MyInt [const][&] x, int)

Then the requirements of that particular operator would be those extracted from the actual signature. If the first argument is taken by value, then it accepts rvalues directly, if it takes the argument by const & then it accepts rvalues if the copy constructor is accessible, if the argument is taken by non constant & then that operator will require lvalues.



来源:https://stackoverflow.com/questions/6692037/why-myclassobj-doesnt-incur-a-compile-error-needs-l-value-just-as-bu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!