forward和move
forwrad和move
std::move一定会将实参转换为一个右值引用,并且使用std::move不需要指定模板实参,模板实参是由函数调用推导出来的。而std::forward会根据左值和右值的实际情况进行转发,在使用的时候需要指定模板实参。
- std::move无条件转换到右值。就其本身而言,它没有move任何东西。
- std::forward只有在它的参数绑定到一个右值上的时候,它才转换它的参数到一个右值。
- std::move和std::forward在运行期都没有做任何事情
#include<iostream>
using namespace std;
template<typename T>
void print(T& t)
{
cout << "lvalue" << endl;
}
template<typename T>
void print(T&& t)
{
cout << "rvalue" << endl;
}
template<typename T>
void TestForward(T && v) //万能引用
{
print(v);
print(std::forward<T>(v));
print(std::move(v));
printf("=============\n");
}
int main()
{
TestForward(1);
int x = 1;
TestForward(x);
return 0;
}
/* 输出
lvalue
rvalue
rvalue
=============
lvalue
lvalue
rvalue
=============
*/
第一个传入的1是一个右值, 在TestForward()中,由于所有形参都是左值,所以v是左值; forward保持了传入的实参,std::forward
第二个传入的x是一个左值,在TestForward()中,由于所有形参都是左值,所以v是左值; forward保持了传入的实参,std::forward
所有形参都是左值
注意:一般而言,forward是要与万能引用一起使用,使用推导出来的模板参数类型在引用折叠后作为强转目标类型(保持实际传入参的左右值属性)
理解原理:(自己理解,若有错误,敬请指出)
forward 相当于 static_cast<T&&>(v);
template<typename T>
void TestForward(T && v)
{
print(static_cast<T&&>(v));
}
即将v强制转换成T&&的类型,这和v本身是左值还是右值无关,和模板的参数类型有关,模板的类型参数的T是万能引用,若传入的实际参数是左值,就是T&,若传入的实参是右值,则推导出来的是T&&。(这里指的是模板里的 T=T& 或 T=T&&)
之后在static_cast<T&&> 会再次发生引用折叠
若模板参数推导出来的是 T& 引用折叠就是(将static_cast<T&&>里的T换成T&) T& && 就还是左值引用
若模板参数推导出来的是 T&& 同理 T&& && 就还是右值 (书里说这要得到的就是一个右值,而不是右值引用,不太理解)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报