c++11新特性之完美转发(std::foward)

CPP11中std::forward的唯一作用是把lvalue转为原来的rvalue 网上对std::forward的功能过度解释, 就一句话 "因为有名字就是lvalue, 为了让这个lvalue类型变回rvalue, 只能使用std::forward.". 阅读详情

完美转发

引用折叠

也就是在c++11里面是没有引用的引用的T& &r=x这时候会发生引用折叠

也就是一般发生在

  • 模板实例化
  • auto decltype typedef的语境中

引用折叠的规则

  • 所有的右值引用折叠到右值引用上还是一个右值引用
  • 所有的其他引用的折叠都会变成左值引用,也就是说,左值引用具有传染性,粘上一个左值引用那就是左值引用了

所以有个概念叫做万能引用

(1)当万能引用(T&& param)绑定到左值时,由于万能引用也是一个引用,而左值只能绑定到左值引用。因此,T会被推导为T&类型。从而param的类型为T& &&,引用折叠后的类型为T&。

​ (2)当万能引用(T&& param)绑定到右值时,同理,右值只能绑定到右值引用上,故T会被推导为T类型。从而param的类型就是T&&(右值引用)。

  1. 当传递给func函数的实参类型为左值Widget时,T被推导为Widget&类别。然后forward会实例化为std::forward<Widget&>,并返回Widget&(左值引用,根据定义是个左值!)
  1. 而当传递给func函数的实参类型为右值Widget时,T被推导为Widget。然后forward被实例化为std::forward<Widget>,并返回Widget&&(注意,匿名的右值引用是个右值!)
  1. 可见,std::forward会根据传递给func函数实参(注意,不是形参)的左/右值类型进行转发。当传给func函数左值实参时,forward返回左值引用,并将该左值转发给process。而当传入func的实参为右值时,forward返回右值引用,并将该右值转发给process函数。

主要跟传参有关

string a("acb");
string&& b = std::move(a);
string c(b);  // 这里其实调用的是拷贝构造
string d(std::forward<string>(b));  // 这里调用的才是移动构造

右值引用是独立于值的,一个右值引用作为函数的形参,在函数的内部转发该参数的时候就已经变成一个左值并不是原来的类型

因为不论 左值引用 还是 右值引用 的变量(或参数)在初始化后,都是左值(参考 [sec|值类别 vs 变量类型]):

命名的右值引用(named rvalue reference)变量 是 左值,但变量类型 却是 右值引用
在作用域内,左值变量 可以通过 变量名(variable name)被取地址、被赋值
所以,返回右值引用变量时,需要使用 std::move()/std::forward() 显式的 [sec|移动转发] 移动转发 或 [sec|完美转发] 完美转发,将变量 “还原” 为右值(右值引用类型)。

**面试答题的两个关键点: **

  • 右值引用其实是一个右值,只是能够绑定到左值,所以调用的时候就会调用构造函数
  • 完美转发里面含有一个有引用折叠,会根据你的实参类型进行相应的转换,右值还是右值,左值还是左值
AniME框架深度体验:用AI自动生成《修真小说》动画全流程记录 本文详细记录了使用开源多智能体框架AniME,结合其核心动画生成模型AniSora V3,将一段修真小说文本自动转化为风格统一动画视频的全流程实战。文章深入解析了从环境搭建、导演智能体任务分解,到多智能体协作生成分镜、角色、动画及最终合成的每一步操作与挑战,为AI驱动的长视频创作提供了宝贵的实践经验与流程优化思路。 阅读详情

相关推荐

灰度重心法实战:从原理到MATLAB代码实现激光条纹中心线提取

本文详细介绍了激光条纹中心线提取的核心方法——灰度重心法。通过物理类比阐释其原理,并提供从图像预处理到MATLAB代码实现的完整实战教程。文章重点解析了算法流程、关键参数调整及常见问题避坑指南,帮助读者快速掌握这一机器视觉与三维测量中的基础且高效的技术。

cake8的博客 462

C++ std::forward()

C++ std::forward(), 完美转发,完美谁起的名字,牛。

心中天堂的专栏 591

Android Studio打包全攻略---从入门到精通

初出茅庐 手动打包怎么手动打包项目写完了,现在需要把应用上传到市场,问题出现—怎么把代码变成.apk(Android的可安装文件)。 1. 创建签名文件 2. 填写好签名参数 3. 生成APK 注意:签名的密码和密匙的密码注意保管,不要忘了,签名文件别泄漏了,也别搞丢了为什么要打包我最开始就有这个疑问,我们的代码不是点了下运行按钮就直接安装到手机上了吗,我们在在项目Project

我早就想,要这样载着你,翻山越岭 2万+

C++11新特性——右值引用、移动语义、完美转发

C++11

m0_67168421的博客 461

EPS+ArcGIS+CASS三剑客:等高线裁剪的完整工作流与避坑指南

本文详细介绍了EPS、ArcGIS和CASS三款软件在等高线裁剪中的协同工作流程与避坑指南。通过发挥各软件优势,解决数据完整性、拓扑准确性和流程可靠性等核心挑战,提升40%以上的工作效率。特别适合大型测绘项目中复杂地形的处理,涵盖数据准备、核心处理到后期优化的全流程。

weixin_30352645的博客 618

方差分析ANOVA、T检验、卡方检验的区别

T检验和ANOVA都是用来看样本之间均值是否相等,但是两者又有什么区别呢? 卡方检验是用来看分类变量之间有没有相关性。 自变量X类型 自变量X组数 因变量Y类型 分析方法 离散(类别) 仅仅2组 连续(均值) t检验 离散(类别) 2组及以上 连续(均值) ANOVA 离散(类别) 2组及以上 离散(类别) 卡方检验 进一步细分 方差分析 从理论上讲,方差分析有两个前提条件,一是因变量Y需要满足正态性要求,二是满足方差齐检验。 方差不齐时可使用‘非参数检验’,同时还可使用wel

itslifeng的博客 4万+

C++之std::forward(完美转发)

std::forward是C++11引入的函数模板,它的作用是实现函数参数的完美转发,通俗的讲就是根据传入的参数,决定将参数以左值引用还是右值引用的方式进行转发。//左值版本//右值版本。

红军不怕远征难,万水千山只等闲 1万+

遥感卫星影像AI数据集格式规范详解、技术原理与数据生产全流程技术手册

本技术手册旨在系统性地梳理遥感卫星影像AI数据集的各类格式标准(涵盖VOC、COCO、YOLO及遥感专用DOTA格式等),深入剖析其背后的技术原理,并详细阐述数据生产的全过程,涵盖预处理、标注、质量控制及数据增强等关键环节。无论您是刚入门的算法工程师,还是资深的数据生产管理者,本手册都将为您提供详实的参考与指引。

panshengwu的博客 1129

C++编程之 std::forward

当向wrapper里面传入1的时候,wrapper推导认为T是一个右值引用int&& ,通过引用折叠原则,int && + && =int&& ,相当于wrapper(int&& arg),同时我们知道了T推导为int&&,那么在向func传递的时候,就是func(std::forward<int&&>(arg)),那么func会以左值引用的形式func(int&& x)调用arg。对于一个模板函数或类模板,当传递一个参数时,如果该参数是左值,那么传递的就是一个左值引用;

Awesomewan的博客 1万+

SpringBoot整合JWT实战:从零构建无状态认证系统,详解Token生成、验证与安全最佳实践

JWT在SpringBoot中的实现与应用 摘要:本文介绍了JWT(JSON Web Token)的基本概念、与Session机制的对比,以及SpringBoot项目中JWT的整合实现。JWT由Header、Payload和Signature三部分组成,具有无状态、跨域支持等优势。文章详细展示了如何在SpringBoot项目中配置JWT环境,封装JWT工具类来实现Token的生成、解析和验证功能,包括密钥管理、自定义声明、签名验证等核心操作。通过对比表格和生活化比喻,帮助读者理解JWT与传统Session的

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 1775

(一)深入理解Bluez协议栈之蓝牙Mesh的支持(1/5)

BlueZ是Linux官方蓝牙协议栈。它是一个基于GNU General Public License (GPL)发布的开源项目,从Linux 2.4.6开始便成为Linux 内核的一部分。如果你是linux平台开发蓝牙的的工程师,肯定会接触过Bluez协议栈,hciconfig,hciattach,hciconfig等工具都是很好用的工具。

3321

C++11 中的移动语义和完美转发

左值、纯右值和将亡值、左值引用和右值引用、移动构造函数与移动语义、std::move 和 std::forward

We choose to go to the moon in this decade and do the other things, not because they are easy, but beacase they are hard. 967

Vins-Fusion 外参camera-imu 标定

Vins-Fusion是一种基于优化的多传感器状态估计器,一大特色是支持实时camera-imu外参校准(相机和IMU之间的旋转)。Vins-Fusion 外参camera-imu校准是利用两帧间计算相机位姿和imu预积分得到位姿,构建最小二乘问题,并通过SVD求解camera-imu外参旋转矩阵。

u010196944的博客 2490

C++ 11 左值,右值,左值引用,右值引用,std::move, std::foward

C++11, 右值引用,move, forward

随便记点东西 2万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

深入理解C++ std::forward:完美转发的原理与应用

在C++模板编程中,我们经常遇到一个棘手问题:如何将参数原封不动地传递给另一个函数?这里的"原封不动"包括参数的值类别(value category)——即到底是左值还是右值。

牟同學的博客 1155

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

C++之完美转发、移动语义(forward、move函数)

C++之完美转发、移动语义(forward、move函数)

weixin_65743593的博客 4162

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

C++起始之路——C++11(上)

💁‍♂️个人主页👇。

2501_93697341的博客 1154

C++ std::forward 详解

完美转发是指在函数模板中,以参数原来的类型,将参数转发到另一个函数。这意味着,如果传递给模板函数的参数是左值,那么转发到其他函数时也应该是左值;如果是右值,转发后也仍然是右值。这样可以避免不必要的拷贝和移动操作,提高代码的效率。在上述代码中,wrapper函数尝试将接收到的参数param转发给innerFunction。然而,存在一个问题:无论param是左值引用还是右值引用,在wrapper函数内部,它都会被视为左值。这是因为一旦进入函数体,参数就有了名称,成为了左值。

yinhezhanshen的专栏 961

【转载】C++11 forward完美转发

前言 继续阅读之前,你最好了解了左值,右值,左值引用,右值引用等概念。 最好阅读了C++11 move带来的高效 引入 这里我借上一篇C++11 move带来的高效中的CMyString类用一下,代码如下 class CMyString{public: CMyString(char* pStr) : m_pStr(NULL) , m_nLen(0) { if (NULL != pStr) { ...

yaoyaoqiekenaoo的博客 205

C++11-forward&move&引用折叠

xx

乐行僧的博客 426

【C++11 之新增容器 array、foward_list、tuple、unordered_(multi)map/set】应知应会

C++11新增容器解析:性能优化与功能补全 C++11引入了多种新容器,主要包括三大类:固定大小数组(std::array)、单向链表(std::forward_list)和无序关联容器(unordered系列)。这些容器针对特定场景进行了优化设计: std::array:类型安全的固定大小数组,替代原生数组,提供STL接口和边界检查,适合栈上固定大小缓冲区场景。 std::forward_list:单向链表,比双向链表std::list节省内存,适合仅需前向遍历和高频头部插入的场景。 无序关联容器(uno

一起学习进步! 627

C++ 11 左值,右值,左值引用,右值引用(emplace用法关键),std::move, std::foward

  转自:https://blog.youkuaiyun.com/xiaolewennofollow/article/details/52559306 这篇文章要介绍的内容和标题一致,关于C++ 11中的这几个特性网上介绍的文章很多,看了一些之后想把几个比较关键的点总结记录一下,文章比较长。给出了很多代码示例,都是编译运行测试过的,希望能用这些帮助理解C++ 11中这些比较重要的特性。 关于左值和右值的...

ylwdi的专栏 580

c++11の的左值、右值以及move,foward

左值和右值的定义 在C++中,可以放到赋值操作符=左边的是左值,可以放到赋值操作符右边的是右值。有些变量既可以当左值又可以当右值。进一步来讲,左值为Lvalue,其实L代表Location,表示在内存中可以寻址,可以给它赋值(常量const类型也可以寻址,但是不能赋值),Rvalue中的R代表Read,就是可以知道它的值。例如: int a=3; a在内存中有地址,而3没有,但是可...

weixin_30855099的博客 109

关于std::move和std::forward

这篇文章介绍的真不错:http://www.cnblogs.com/catch/p/3507883.html总结起来:1. std::move是将左值变成右值减少不必要的拷贝;2. std::forward保持一个值的左值和右值特性不变,以变传给既能接受左值又能接受右值的函数,例:template TYPE* acquire_obj(ARG&& arg) { return new TYPE(

左雪菲的专栏 1394
上一篇: 类对象只在栈或者堆里面创建
下一篇: 内存池详解
黑猫爱小鹿
博客等级 码龄8年 1万+粉丝 205原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值