为什么这个对象被认为是右值
Why is this object considered an rvalue?
为什么我传递给ClassA
构造函数的对象被认为是右值(临时的)?我知道将参数设置为 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;
}
这里的右值是ClassA(a)
表达式。
ClassA b = ClassA(a);
这就是复制初始化,因此它将尝试调用 ClassA
的复制构造函数,结果为 ClassA(a)
,这是一个右值。您已声明复制构造函数采用 ClassA&
,该构造函数无法绑定到右值,因此出现错误。
正如您所指出的,最好的解决方法是将const
添加到复制构造函数,以便它可以绑定到 rvalues,但您也可以使用直接初始化或复制初始化而不进行类型转换:
ClassA b (a);
ClassA b {a}; //C++11
ClassA b = a;
请注意,尽管ClassA b = ClassA(a);
需要一个有效的复制构造函数,但该副本可能会被省略。这目前是可选的,但在某些时候可能是强制性的。
相关文章:
- 为什么rand()的使用被认为是不好的
- 访问数据成员(本身是对象)的数据成员,就好像它们是类成员一样
- 为什么 std::shared_ptr 被认为是"heavy"和"expensive",但 std::array "same perfprmance as plain (c-style) arrays
- 如何在类中递增单独的变量,而不是对象本身?
- 一个C头文件可以被认为是一个接口吗
- 为什么const char*和const char[]作为函数参数被认为是等价的
- 为什么12.0==11.999999999999999999被认为是真的
- 如何获取指向类(而不是对象)的引用/指针
- 这会被认为是糟糕的编程实践吗?
- 为什么这被认为是恒定的?
- 抽象类/接口中的空方法是否被认为是一种好的做法?
- 如果我具有调用其其他实例之一的超载函数,它是否被认为是递归功能
- std::unique_ptr可以被认为是一个monad吗?
- C++ 指向类的指针和/或引用是否被认为是"movable"?
- 在另一个对象 B 中创建对象 A 时,对象 A 是否是对象 B 的本地对象,对象 A 是否会存在于对象 B 的实例化之外?
- static_cast实际上不是对象类型的类型是未定义的行为吗?
- 使用成员函数更改对象或返回并分配它是否被认为是更好的做法?
- 为什么像cin,cout,string等东西被认为是对象
- c++:"pointer to const"指向的对象是否被认为是不变的还是不可修改的?
- 为什么这个对象被认为是右值