临时 C++ 对象是左值吗?

Bre*_*ala 3 c++

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

class A {
  int a=0;
};

A returnsA(void)
{
  static A myA;

  return myA;
}

void works(void)
{
  A anotherA;

  returnsA() = anotherA;
}
Run Code Online (Sandbox Code Playgroud)

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

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

我期待的行为更像这样,但无法编译:

int returnsint(void)
{
  static int i=0;

  return i;
}

void doesntwork(void)
{
  int anotherint=0;

  returnsint() = anotherint;
}
Run Code Online (Sandbox Code Playgroud)

有人可以进一步启发我了解这种行为吗?

M.M*_*M.M 5

对象不是左值或右值。单词左值右值表达式类别。他们对表达式进行分类,而不是对对象进行分类。


对于线路:

returnsA() = anotherA;
Run Code Online (Sandbox Code Playgroud)

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

A& A::operator=(A const&);
Run Code Online (Sandbox Code Playgroud)

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

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


如果您想阻止您的班级接受此类作业,请参阅此处。至于为什么默认赋值运算符不能以这种方式工作,请参阅此处


归档时间:

查看次数:

308 次

最近记录:

2 年,7 月 前