为什么是 myClassObj++++不会产生编译错误:'++'需要像内置类型一样的左值吗?

发布于 2024-11-23 23:10:06 字数 780 浏览 1 评论 0原文

为什么 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

三寸金莲 2024-11-30 23:10:17

最后,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 call operator++(int) on rvalues.

墨落成白 2024-11-30 23:10:17

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).

拿命拼未来 2024-11-30 23:10:17

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

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

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

那么该特定运算符的要求将是从实际签名中提取的要求。如果第一个参数按值获取,则它直接接受右值,如果它通过 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:

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.

星星的轨迹 2024-11-30 23:10:16

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

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

柠檬心 2024-11-30 23:10:16

如果您想模拟内置行为,实际上有一个非常简单的解决方案:将返回值设为 const

MyInt const operator++(int) { … }

几年前,关于用户定义的运算符是否应该完全< /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:

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.

送君千里 2024-11-30 23:10:15

不,重载运算符不是运算符 - 它们是函数。所以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 to myobj.operator++(0).operator++(0);
Caling a member function (including overloaded operator) on a temprorary object of class type is allowed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文