右值引用和用户定义的转换

rvalue references and user defined conversion

我想弄清楚下面代码中发生了什么(它的灵感来自 shared_ptr(unique_ptr&&) 构造函数)。

#include <iostream>
using namespace std;

class A {};

class B {
public:
    B(const A&) {
        cout << "ctor from A&\n";
    }
};

void f(B&&) { cout << "f(B&&)\n"; };
void f(const B&) { cout << "f(const B&)\n"; }

int main() {
    A a;
    f(a);
}

我想了解它是如何工作的。为什么右值是转换的结果并调用 f(B&&)

该函数不接受 A 类型的对象。但是,它确实接受类型为 B 的对象,并且 A 可以通过隐式转换构造函数转换为 B。转换的结果是纯右值。当参数是纯右值时,右值引用重载比 const 左值引用更匹配。

基本上,调用 f(a) 使用接受 AB 的构造函数创建一个临时(右值)B 对象。然后重载决议开始找出哪个 f 是更好的匹配。

此处适用的重载解析规则是over.match.best#over.ics.rank-3.2.3

S1 and S2 include reference bindings ([dcl.init.ref]) and neither refers to an implicit object parameter of a non-static member function declared without a ref-qualifier, and S1 binds an rvalue reference to an rvalue and S2 binds an lvalue reference

采用右值引用的重载优于采用左值引用的重载。 (链接规则中有一个类似的例子)。