为什么这段C++代码传入左值却输出RValue而非LValue?
问题原因解析
你遇到的问题核心是错误使用了完美转发的前提条件,std::forward的转发行为完全依赖传入的模板参数T的类型,且完美转发要求承载转发逻辑的函数形参必须是T&&格式的转发引用,你定义的call函数形参为按值传递,直接破坏了转发的类型推导逻辑:
- 当你在
main中传入左值std::string t调用call(t)时,因为call的形参是T other(按值传递),模板参数T会被推导为纯值类型std::string,不会携带任何引用修饰符 std::forward的规则为:如果模板参数T是非引用类型,会将传入的参数转为右值引用;仅当T是左值引用类型时,才会将参数转为左值引用- 此时
T为std::string,std::forward<std::string>(other)会将call函数内的局部变量other转为右值,自然匹配到接收右值引用的check重载,输出Rvalue
修复方案
如果需要实现预期的完美转发效果,需要将call函数的形参改为转发引用格式:
#include <iostream> #include <string> template<typename T> void check(T&& other) { std::cout << "Rvalue" << std::endl; } template<typename T> void check(T& other) { std::cout << "Lvalue" << std::endl; } // 将形参改为T&& 格式的转发引用 template<typename T> void call(T&& other) { check(std::forward<T>(other)); } int main() { std::string t = "Cool"; call(t); // 此时输出Lvalue,符合预期 }
修改后调用call(t)时,模板参数T会被推导为std::string&,根据引用折叠规则形参会变为左值引用,std::forward<std::string&>(other)会返回左值,最终匹配到左值版本的check重载。
内容的提问来源于stack exchange,提问作者user16273653
相关产品推荐
相关产品推荐

