为什么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);
允许在类类型的临时对象上调用成员函数(包括重载操作符)。
因为对于用户定义类型,操作符重载实际上只是函数调用,因此服从函数调用的语义。
如果你想模拟内置行为,实际上有一个非常简单的解决方案:使返回值const
:
MyInt const operator++(int) { … }
几年前,有一个关于用户定义操作符是否应该完全模拟内置行为的争论。我不确定目前哪个学派占了上风,但是使operator++(int)
的返回类型const
是实现这一目标的一种方法。
最后,MyInt::operator++(int)
只是另一种方法。同样的规则也适用。因为你可以在右值上调用方法,所以你可以在右值上调用operator++(int)
。
myint++返回类似于myint(2)的值。这和MyInt(2)++很相似。在operator++函数中创建了一个临时类,您正在对临时类进行加1操作。返回后,在下一条语句结束时(这里是第二个++操作符),它将被删除。
问题是整型和用户定义类型的后增量运算符的要求是不同的。特别是,用户定义的后增量运算符实现为成员函数,允许使用右值。
如果您将操作符实现为自由函数:
MyInt operator++(MyInt [const][&] x, int)
则该特定操作符的需求将是从实际签名中提取的需求。如果第一个实参被value接受,则直接接受右值;如果实参被const &
接受,则在复制构造函数可访问的情况下接受右值;如果实参被非常量&
接受,则该操作符将需要左值。