构造的临时对象是左值?

时间:2014-08-19 22:27:00

标签: c++ constructor temporary rvalue

假设我有一个名为Foo的类,带有复制赋值运算符,我认为这是:

Foo() = Foo();

是不允许的,因为我想(抱歉,再次)Foo()是一个右值(所以我不能分配给它),是一个临时对象。 显然,我试图使这段代码工作,并且它正常工作,显示一些字符串以验证我的程序正确使用了复制赋值运算符。

我错了吗?或者这是一种错误?有什么用处?

4 个答案:

答案 0 :(得分:8)

Foo()是左值,这是肯定的。

但表达式Foo() = Foo()相当于Foo().operator=(Foo())。即使Foo()是一个右值,你仍然可以在它上面调用一个成员函数,甚至是一个修改它的成员函数。

当然,在作业的左侧不允许使用基本类型的右值。在这方面,基本类型的处理方式与用户定义的类型不同。

这就是为什么,在C ++中," lvalue"不应被定义为"可以出现在作业左侧的东西"!

答案 1 :(得分:1)

Foo有一个重载的复制赋值/移动赋值运算符。可以隐式提供任何一个,也可以自己编写。无论哪种方式,因为Foo()是一个实例,它能够像常规成员函数一样访问成员函数运算符。

答案 2 :(得分:1)

你是对的,=运算符通常要求其左操作数是左值。但是,当运算符应用于已经重载的类型时,它们将转换为函数调用。您的代码相当于:

Foo().operator=(Foo())

.运算符会很乐意接受右值作为左操作数。

答案 3 :(得分:0)

对象不能是" rvalue"或"左值"。如果不同类型的值(左值,右值,右值,右值等)适用于表达式,则用于访问对象,而不是对象本身。

在你的情况下,功能强制转换表达式Foo()确实会产生一个临时对象作为右值。但是,在该临时对象的任何方法中,您可以使用表达式*this,它将公开与左值相同的临时对象。换句话说,普遍认为临时物体是右值是明显不正确的。这总是一个用于访问对象的表达式的问题。

您可以在作业的左侧使用它,这并不奇怪。 "左值"要求仅适用于内置赋值运算符。对于重载赋值运算符,没有这样的要求,并且从来没有这样的要求。在您的情况下,您使用的是重载运算符。