测试std::forward时遇困惑:为何此场景下模板参数A为引用类型?
关于std::forward测试中模板参数推导的疑惑解答
这其实是C++模板推导里**转发引用(universal reference)**的特性在起作用,咱们一步步拆解来看:
核心原因:转发引用的模板推导规则
你的函数模板参数是A&&,这不是普通的右值引用——只有当模板参数形如T&&且T是未确定的模板参数时,它才是转发引用(也叫万能引用)。当你传入一个左值(比如代码里的int* p,p是左值)时,模板参数推导会把A推导为左值引用类型,也就是int*&,而不是你预想的int*。
这时候结合C++的引用折叠规则:
- 只要有一个是左值引用,折叠结果就是左值引用(
& + & = &,& + && = &) - 只有两个都是右值引用时,才会折叠成右值引用(
&& + && = &&)
所以函数参数A&&代入A=int*&后,就变成了int*& &&,最终折叠为int*&,完美匹配传入的左值p。
对应代码输出的解释
咱们对应你的输出010和100来分析:
- 第一行输出
010:因为A的实际类型是int*&,它是左值引用,不是指针类型,也不是右值引用,所以std::is_pointer<A>::value为0,std::is_lvalue_reference<A>::value为1,std::is_rvalue_reference<A>::value为0。 - 第二行输出
100:std::remove_reference<A>::type会移除引用属性,得到的类型是int*,所以std::is_pointer<B>::value为1,剩下两个引用判断自然都是0。
关于A&和A&&的类型问题
既然A是int*&,那结合引用折叠规则:
A&等价于int*& &,折叠后结果是int*&(左值引用)A&&等价于int*& &&,折叠后结果依然是int*&(左值引用)
简单来说,转发引用的推导规则就是:传入左值时模板参数推导为左值引用,传入右值时推导为非引用类型,通过引用折叠就能保持原有的值类别,这也是std::forward能实现完美转发的核心原理。
内容的提问来源于stack exchange,提问作者MorJ
相关产品推荐
相关产品推荐

