C++ 为什么是myClassObj++++;不';t发生编译错误:'++';像buildin类型一样需要l值吗?
为什么myint+++可以用VS2008编译器和gcc 3.42编译器很好地编译??我希望编译器说需要左值,示例见下文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
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:在内部运算符+++
的计算完成之后,在外部运算符+++
输入之前,这里有一个序列点。这正是我想表达的观点。这是不正确的:重载运算符既是运算符又是函数。重要的一点是,对用户定义运算符的要求是运算符实现的要求,这可能因您如何实现而有所不同。在这种特殊情况下,作为成员函数。