C++中左值实参调用右值引用重载为何发生跨类型转换?
为何右值引用重载会触发跨类型隐式转换?
先看代码运行结果的核心原因:非const右值引用(T&&)无法直接绑定到左值,当你传递左值(比如iv、fv)调用重载函数时,编译器找不到直接匹配的重载,只能通过隐式转换生成临时右值来匹配对应的重载。
具体代码分析
1. 字面量调用(f(2)、f(1.0f))
2是int类型的右值字面量,直接匹配f(int&&),输出2i;1.0f是float类型的右值字面量,直接匹配f(float&&),输出1f;
这部分符合预期,因为字面量本身就是右值,能直接绑定到对应的右值引用参数。
2. 左值变量调用(f(iv)、f(fv))
- 对于
f(iv):iv是int类型的左值,无法直接绑定到f(int&&)(非const右值引用不接受左值)。此时编译器会寻找可行的重载:将iv隐式转换为float类型,生成一个float临时对象(右值),这个临时对象可以绑定到f(float&&),因此调用该重载,输出2f。 - 对于
f(fv):fv是float类型的左值,无法直接绑定到f(float&&)。编译器将fv隐式转换为int类型,生成int临时对象(右值),绑定到f(int&&),输出1i。
对应的C++规则
- 右值引用的绑定规则:非const的右值引用(
T&&)只能绑定到右值(包括临时对象、字面量、std::move转换后的左值),不能直接绑定到左值。这是为了防止意外修改左值的内容。 - 重载决议的可行函数选择:当没有直接匹配的函数时,编译器会尝试通过隐式转换生成可行的函数调用。在你的例子中,左值无法匹配同类型的右值引用重载,只能通过跨类型转换生成临时右值,匹配另一个类型的右值引用重载。
- 隐式转换的优先级:这里不存在多个可行函数的冲突,因为每个左值调用时只有一个重载能通过隐式转换匹配(另一个重载的同类型右值引用无法绑定左值,也没有其他转换路径),所以编译器直接选择这个可行的重载。
如果想要让左值变量调用同类型的重载,需要显式使用std::move将左值转换为右值,比如f(std::move(iv))会匹配f(int&&),f(std::move(fv))会匹配f(float&&)。
内容的提问来源于stack exchange,提问作者user22879756
相关产品推荐
相关产品推荐

