当前位置: 首页 > article >正文

【C++11】折叠引用和完美转发

目录

  • 一. 前言
  • 二. 引用折叠
    • 引用折叠的规则
  • 三. 完美转发
    • 完美转发适用场景
    • 完美转发底层实现
      • 思考1
      • 思考2

一. 前言

在函数传参时,如果想保持某个参数的属性不改变,需要完美转发,而完美转发的实现需要折叠引用的帮助

二. 引用折叠

在语法上,c++不能定义引用的引用,如 int & && r=i,这样会报错,但是通过模板或typedef的类型可以构成引用的引用,

引用折叠的规则

  1. 除了右值引用的右值引用,其他组和都是左值
  • T& & → T& (左值引用的左值引用折叠为左值引用)

  • T& && → T& (左值引用的右值引用折叠为左值引用)

  • T&& & → T& (右值引用的左值引用折叠为左值引用)

  • T&& && → T&& (右值引用的右值引用折叠为右值引用)

  1. 通过引用规则我们发现,T&&的结果可以保持T本身的属性,所以T&&也被称为万能引用,

三. 完美转发

完美转发适用场景

从下图可以看出,在最开始Function函数中传入的是右值,但在Func中却变成了左值,这是由于右值表达式的属性是左值,
在这里插入图片描述

这样就破坏了最开始传入的值的属性
想要保持表达式的属性,就需要用完美转发来解决,见下图
在这里插入图片描述

完美转发底层实现

完美转发的本质是函数模板,通过引用折叠实现,在forward内部进行强转,然后再引用折叠返回,
std::remove_reference_t& t 移除T最外层的引用修饰,使不管传入什么类型,t的类型都是左值引用类型

思考1

思考1:为什么需要保证t的类型是左值引用?
直接用原类型不行么 T&& forward(T&& t)
传入左值时,T被推导为T&,T&->T&,没有问题
传入右值时,T被推导为T,T->T&&,左值向右值转化,危险操作

template <class T>
T&& forward(std::remove_reference_t<T>& t)
{//std::remove_reference_t<T> 类型萃取模板,移除T的最外层引用修饰,return static_cast<T&&>(t);·
}
template <class T>
void Function(T&& t)
{//Func(std::forward<T>(t));Func(forward<T>(t));//Func(t);
}int main()
{int&& n = 10;Function(n);return 0;
}

思考2

思考2:为什么需要用std::remove_reference_t& 来移除最外层修饰的引用,
T&& forward(T& t) 不行么?
传入左值时
T& && forward(T& & ) 实例化-> T& forward(T & ) 没有问题
传入右值时
T&& && forward(T&& & ) 实例化-> T&& forward(T & ) 看似没有问题
虽然 int&& & 理论上可以折叠为 int&,但 C++ 类型系统禁止直接声明这种组合:

http://www.lryc.cn/news/2398102.html

相关文章:

  • 数据结构:递归:自然数之和
  • 网易 - 灵犀办公文档
  • 【C++】模板与特化技术全面教程(claude sonnet 4)
  • ABAP设计模式之---“高内聚,低耦合(High Cohesion Low Coupling)”
  • RagFlow优化代码解析(一)
  • 【python与生活】用 Python 从视频中提取音轨:一个实用脚本的开发与应用
  • 深度强化学习赋能城市消防优化,中科院团队提出DRL新方法破解设施配置难题
  • 云原生周刊:探索 Gateway API v1.3.0
  • 008房屋租赁系统技术揭秘:构建智能租赁服务生态
  • Python训练打卡Day41
  • spring-boot-admin实现对微服务监控
  • Linux 权限管理入门:从基础到实践
  • Mycat的监控
  • Glide源码解析
  • 7.RV1126-OPENCV cvtColor 和 putText
  • Android 之 kotlin 语言学习笔记二(编码样式)
  • Redisson单机模式
  • 数据结构第6章 图(竟成)
  • 机器人现可完全破解验证码:未来安全技术何去何从?
  • CppCon 2014 学习:(Costless)Software Abstractions for Parallel Architectures
  • 网络爬虫 - App爬虫及代理的使用(十一)
  • Kafka集群部署(docker容器方式)SASL认证(zookeeper)
  • 【python爬虫】利用代理IP爬取filckr网站数据
  • 群晖 NAS 如何帮助培训学校解决文件管理难题
  • NLP学习路线图(十八):Word2Vec (CBOW Skip-gram)
  • P1438 无聊的数列/P1253 扶苏的问题
  • 嵌入式学习笔记 - 新版Keil软件模拟时钟Xtal灰色不可更改的问题
  • k8s的出现解决了java并发编程胡问题了
  • 如何利用大语言模型生成特定格式文风的报告类文章
  • 黑马Java面试笔记之 集合篇(算法复杂度+ArrayList+)