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(v)就保持了右值, move强制转成右值

第二个传入的x是一个左值,在TestForward()中,由于所有形参都是左值,所以v是左值; forward保持了传入的实参,std::forward(v)就保持了左值, 而move会强制转成右值

所有形参都是左值

注意:一般而言,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&& && 就还是右值 (书里说这要得到的就是一个右值,而不是右值引用,不太理解)
  
  

posted @   预期  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
点击右上角即可分享
微信分享提示