为什么这个对象被认为是rvalue?

4

为什么我传入 ClassA 构造函数的对象被认为是一个临时的 rvalue 呢?我知道将参数设置为 const 可以消除错误,但我想了解发生了什么。

这种行为在函数调用中可以正常工作,但在构造函数中却不行吗?

#include <iostream>

using namespace std;

class ClassA {
public:
   ClassA() {}
   ClassA(ClassA&) {}
};

void f(ClassA&) {}

int main() {
   ClassA a;

   // Invalid initialization of non-const reference of type 'ClassA&' from an
   // rvalue of type 'ClassA'
   ClassA b = ClassA(a); 

   // Works fine
   f(a);

   return 0;
}

f(ClassA(a)) 也是无效的。 - cpplearner
1个回答

10
这里的 rvalue 是 ClassA(a) 表达式。
ClassA b = ClassA(a);

这是复制初始化,因此它将尝试使用ClassA(a)的结果调用ClassA的复制构造函数,该结果是一个右值。您声明了复制构造函数需要一个ClassA&,无法绑定到右值,因此会出现错误。
最好的解决方法是,如您所指出的,向复制构造函数添加const以便它可以绑定到右值,但您也可以使用直接初始化或不带类型转换的复制初始化。
ClassA b (a);
ClassA b {a}; //C++11
ClassA b = a;

请注意,尽管ClassA b = ClassA(a);需要一个有效的复制构造函数,但复制很可能会被 省略。这目前是可选的,但在某些时候可能会变为 强制执行

ClassA b = a; 也可以工作,并且也是复制构造。 - sp2danny

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接