C++ | std::forward
-
引用折叠
template <class T> void func(T && arg);
若一个右值引用(
&&
)参数被一个左值或左值引用初始化,那么引用将折叠为左值引用。(即:T&& & –> T&)int a = 1; func(a); // func()中 参数arg 变成 int &类型 int &ref = a; func(ref); // func()中 参数arg 变成 int &类型
若一个右值引用参数被一个右值初始化,那么引用将折叠为右值引用。(即:T&& && 变成 T&&)。
func(10); // func()中 参数arg 仍是 int &&类型
一个左值引用参数不管是被一个左值还是右值初始化,引用都不能折叠,仍为左值引用(即:T& & –>T&,T& && –>T&)。
-
为什么需要引入
std::forward
?有这么个例子:
template <class T> void func(T && arg){ cout << &arg; }
这个函数是可以通过编译且运行的,并且在调用时无论传入一个左值(引用)或者右值,都不影响函数将参数
arg
视作左值并取其地址。这也就说明了,一个右值引用参数在函数中使用时,依旧会被当成一个左值去使用。
另一个例子是:
template <class T> Data* func(T && arg){ return new Data(arg); }
假定有一个类
Data
,这个类中实现了复制构造和移动构造函数,倘若使用以上写法,在函数func
中,会调用Data
的复制构造函数来初始化一个Data
对象,而不是其移动构造函数。而使用
std::forward
就可以解决这个问题:template <class T> Data* func(T && arg){ return new Data(std::forward<T>(arg)); }
将参数
arg
的右值引用属性保留并作为右值引用参数传给Data
,所以称为完美转发。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通