临时C++对象是否为左值?

Are temporary C++ objects lvalues?

本文关键字:是否 C++ 对象 临时      更新时间:2023-10-16

我对以下代码感到困惑,它(令我惊讶(编译:

class A {
int a=0;
};
A returnsA(void)
{
static A myA;
return myA;
}
void works(void)
{
A anotherA;
returnsA() = anotherA;
}

我在标准或网络上找不到任何表明它不应该编译的内容。 对我来说,这似乎很奇怪。

我想returnsA()返回一个对象(myA的副本(,所以我们在其上调用默认的复制赋值运算符,anotherA被复制分配给返回的对象,然后超出范围并被销毁。

我期待的行为更像这样,它不会编译:

int returnsint(void)
{
static int i=0;
return i;
}
void doesntwork(void)
{
int anotherint=0;
returnsint() = anotherint;
}

任何人都可以进一步启发我这种行为吗?

对象不是左值或右值。值和右值这两个词是表达式类别。它们对表达式进行分类,而不是对对象进行分类。


对于行:

returnsA() = anotherA;

由于=的操作数是类类型,因此搜索重载运算符函数。operator=的特殊之处在于,如果用户没有显式重载它,则会生成默认重载。该重载是具有签名的成员函数:

A& A::operator=(A const&);

并将调用returnsA() = anotherA;转换为returnsA().operator=(anotherA);,这是成员算子重载的基本机制。

表达式returnsA()具有类别prvalue。但是,在 prvalue 表达式上调用成员函数是完全可以的,所以这里没有问题。


如果您想劝阻您的班级不要接受此类作业,请参阅此处。有关默认赋值运算符不以这种方式工作的原因,请参阅此处。