关于C++引用折叠规则的疑问及&&+&&→&&场景示例请求
C++引用折叠规则验证与场景示例
代码理解验证
针对你的实验代码,逐个分析调用的实际等价情况:
func(a);
你的理解错误。a是左值,根据通用引用的模板参数推导规则,当T&&绑定左值时,T会被推导为左值引用类型(即int&),因此实际调用的是func<int&>(a)。此时参数t的类型为int& &&,经过引用折叠后最终变为int&。func(10);10是右值,通用引用绑定右值时,T推导为非引用类型int,实际调用func<int>(10),参数t的类型为int&&,无引用折叠发生。func(std::move(a));std::move(a)将左值转换为右值引用(本质仍属于右值范畴),因此T推导为int,实际调用func<int>(std::move(a)),参数t的类型为int&&。func(b1);
你的理解正确。b1是int&类型的左值,T推导为int&,调用func<int&>(b1),参数t的类型int& &&经过引用折叠变为int&,符合& + && → &的规则。func(b2);
你的理解错误。注意:所有命名的引用都是左值——哪怕b2是int&&类型,它作为命名变量仍属于左值。因此传递b2时,通用引用绑定左值,T推导为int&,实际调用func<int&>(b2),参数t的类型int& &&折叠为int&,同样符合& + && → &的规则。
&& + && → &&引用折叠场景示例
这类折叠发生在T被推导为右值引用类型,或显式指定T为右值引用时,结合通用引用的&&触发折叠:
场景1:显式指定模板参数为右值引用
template<typename T> void func(T&& t) {} int main() { int a = 10; // 显式指定T为int&&,此时T&&即int&& &&,折叠为int&& func<int&&>(std::move(a)); }
场景2:嵌套模板推导中的右值引用传递
template<typename T> void inner_func(T&& t) {} template<typename T> void outer_func(T&& t) { // 当outer_func的T被推导为int&&时,传递给inner_func的T&&即int&& &&,折叠为int&& inner_func(std::forward<T>(t)); } int main() { int a = 10; outer_func(std::move(a)); }
场景3:typedef/别名中的右值引用折叠
using IntRRef = int&&; template<typename T> void func(T&& t) {} int main() { int a = 10; // T指定为IntRRef(即int&&),T&&即int&& &&,折叠为int&& func<IntRRef>(std::move(a)); }
内容的提问来源于stack exchange,提问作者coin cheung
相关产品推荐
相关产品推荐

