为什么是 myClassObj++++不会产生编译错误:'++'需要像内置类型一样的左值吗?
为什么 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 ??
}
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 ??
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
最后,
MyInt::operator++(int)
只是另一种方法。同样的规则适用。由于您可以对右值调用方法,因此您可以对右值调用operator++(int)
。In the end,
MyInt::operator++(int)
is just another method. The same rules apply. Since you can call methods on rvalues, you can calloperator++(int)
on rvalues.myint++ 返回类似于 MyInt(2) 的内容。因此,这与执行 MyInt(2)++ 类似。在operator++函数中创建了一个临时类,并且您正在递增该临时类。返回后,下一条语句完成后它就会被删除(这里是第二个 ++ 运算符)。
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).
问题在于,整型类型和用户定义类型的后自增运算符的要求是不同的。特别是,作为成员函数实现的用户定义的后增量运算符允许使用右值。
如果您将运算符实现为自由函数:
那么该特定运算符的要求将是从实际签名中提取的要求。如果第一个参数按值获取,则它直接接受右值,如果它通过 const & 获取参数,则如果复制构造函数可访问,则它接受右值,如果参数由非常量获取
&
那么该运算符将需要左值。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:
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.因为对于用户定义类型,运算符重载实际上只是函数调用,因此遵循函数调用的语义。
Because for user-defined types, operator overloads are literally just function calls, and so obey the semantics of function calls.
如果您想模拟内置行为,实际上有一个非常简单的解决方案:将返回值设为
const
:几年前,关于用户定义的运算符是否应该完全< /em> 对内置行为建模。我不确定目前哪种思想流派占上风,但将返回类型设置为
operator++(int)
const
是实现这一目标的一种方法。If you want to emulate the built-in behaviour there’s actually a very simple solution: make the return value
const
: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.不,重载运算符不是运算符 - 它们是函数。所以GCC接受是正确的
那。
myobj++++;
相当于myobj.operator++(0).operator++(0);
允许在类类型的临时对象上调用成员函数(包括重载运算符)。
No, overloaded operators are not operators - they're functions. So GCC is correct to accept
that.
myobj++++;
is equivalent tomyobj.operator++(0).operator++(0);
Caling a member function (including overloaded operator) on a temprorary object of class type is allowed.