Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么是myClassObj++++;不';t发生编译错误:'++';像buildin类型一样需要l值吗?_C++_Operator Overloading_Lvalue - Fatal编程技术网

C++ 为什么是myClassObj++++;不';t发生编译错误:'++';像buildin类型一样需要l值吗?

C++ 为什么是myClassObj++++;不';t发生编译错误:'++';像buildin类型一样需要l值吗?,c++,operator-overloading,lvalue,C++,Operator Overloading,Lvalue,为什么myint+++可以用VS2008编译器和gcc 3.42编译器很好地编译??我希望编译器说需要左值,示例见下文 struct MyInt { MyInt(int i):m_i(i){} MyInt& operator++() //return reference, return a lvalue { m_i += 1; return *this; } //operator++ need it's ope

为什么myint+++可以用VS2008编译器和gcc 3.42编译器很好地编译??我希望编译器说需要左值,示例见下文

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 ??
}

不,重载运算符不是运算符-它们是函数。因此,GCC是正确的 那个

myobj++
相当于
myobj.operator++(0).operator++(0)

允许在类类型的临时对象上校准成员函数(包括重载运算符)。

因为对于用户定义的类型,运算符重载实际上只是函数调用,因此遵循函数调用的语义。

最后,
MyInt::operator++(int)
只是另一种方法。同样的规则也适用。因为可以对右值调用方法,所以可以对右值调用
运算符++(int)

myint++返回类似于myint(2)的内容。所以,它类似于MyInt(2)++。将在operator++函数中创建一个临时类,并且您将递增该临时类。返回后,下一条语句完成后,它就会被删除(这里是第二个++运算符)。

问题在于,对于整数类型和用户定义类型,后增量运算符的要求是不同的。特别是,作为成员函数实现的用户定义的postincrement运算符允许使用右值

如果已将运算符作为自由函数实现:

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

然后,该特定操作员的要求将是从实际签名中提取的要求。如果第一个参数按值取值,则直接接受右值;如果第一个参数按
const&
取值,则如果复制构造函数可访问,则接受右值,如果参数由非常量
&
获取,则该运算符将需要左值。

如果要模拟内置行为,实际上有一个非常简单的解决方案:使返回值
为常量

MyInt const operator++(int) { … }

几年前,关于用户定义的操作符是否应该准确地为内置行为建模,存在着一场争论。我不确定目前哪个学派占上风,但将返回类型设置为
运算符++(int)
常量是实现这一点的一种方法。

是的。在没有插入序列点的情况下修改
i
两次,这是错误的。@Oli,@MSalters:+++i格式正确,但它有UB。我不认为编译器接受它是错误的:)而是返回一个const MyInt,它实现了您想要的,并且是更好的实践,因为它使用户很难对您的类做“错误”的事情。看看C++中从操作符+中返回const对象的有效C++章节。另一个愚蠢的问题,在实际代码中永远不会出现。它不仅不可读。这是未定义的行为。@MSalters:在内部
运算符+++
的计算完成之后,在外部
运算符+++
输入之前,这里有一个序列点。这正是我想表达的观点。这是不正确的:重载运算符既是运算符又是函数。重要的一点是,对用户定义运算符的要求是运算符实现的要求,这可能因您如何实现而有所不同。在这种特殊情况下,作为成员函数。