#include <iostream>
using namespace std;
class foo {
public:
foo() {}
foo(const foo& other) {cout << "foo's copy constructor " << endl;}
foo(foo&& other) {cout << "foo's move constructor " << endl;}
foo(const foo&& other) {cout << "foo's move constructor with const ref ref" << endl;}
};
class bar {
public:
bar(const foo& f) : f_(move(f)) {}
foo f_;
};
int main()
{
foo f;
bar b(f);
}
在上面的代码中,如果没有 move 构造函数 -- foo(const foo&& other),右值引用 move(f) 会隐式转换为 const引用并因此调用 foo 的复制构造函数。
我的问题是为什么 const 右值引用隐式转换为 const 引用而不是编译器错误?具体来说,如果我注释掉最后一个移动构造函数,则会调用 foo 的复制构造函数。
最佳答案
一些具有相同引用绑定(bind)的更简单的代码:
int main()
{
const foo f;
const foo& g = std::move(f);
const foo&& h = std::move(f);
}
表达式 std::move(f)
最好描述为 const foo
类型的 xvalue。
因此,我们有一个由 const foo
类型的 xvalue 初始化的引用。
g
和h
都是合法的,引用直接绑定(bind)。 const foo&&
只能绑定(bind)到右值,但 const foo&
可以绑定(bind)到左值和右值。 (x 值是右值)。
没有标题中建议的隐式转换,引用直接绑定(bind)到初始化程序指定的对象。
在发布的代码中,两个构造函数之间存在重载解析,其绑定(bind)与我的示例中的 g
和 h
相同。重载解析选择参数类型 const foo&&
作为比 const foo&
更好的匹配类型 const foo
和类别“xvalue”的参数,因为有是一个排序规则,如果其他条件相同,右值参数更喜欢右值引用。
但是,如果您删除这两个构造函数中的任何一个,那么另一个构造函数将被选择。
关于c++ - 为什么 const 右值引用隐式转换为 const 引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61093451/