c++ - 为什么 const 右值引用隐式转换为 const 引用?

标签 c++

#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 初始化的引用。

gh都是合法的,引用直接绑定(bind)。 const foo&& 只能绑定(bind)到右值,但 const foo& 可以绑定(bind)到左值和右值。 (x 值是右值)。

没有标题中建议的隐式转换,引用直接绑定(bind)到初始化程序指定的对象。


在发布的代码中,两个构造函数之间存在重载解析,其绑定(bind)与我的示例中的 gh 相同。重载解析选择参数类型 const foo&& 作为比 const foo& 更好的匹配类型 const foo 和类别“xvalue”的参数,因为有是一个排序规则,如果其他条件相同,右值参数更喜欢右值引用。

但是,如果您删除这两个构造函数中的任何一个,那么另一个构造函数将被选择。

关于c++ - 为什么 const 右值引用隐式转换为 const 引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61093451/

相关文章:

c++ - 在无锁单链表的开头插入节点时使用的正确内存顺序是什么?

c++ - qt c++ QDialog 打开新文件

c++ - Visual Studio 中指向类数据成员的 C++ 指针的地址

c++ - 关于boost bimap中unordered_multiset_of的问题

c++ - 重载 ostream << 运算符

c++ - 使用现代 OpenGL 渲染我的第一个三角形

android - std::map 链接器错误 ndk r8c with APP_STL := gnuSTL_static

c++ - 与引号连接会导致错误

c++ - 同一地址的变量如何产生 2 个不同的值?

c++ - 在Cmake中构建Assimp时出错