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

【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.lqws.cn/news/95563.html

相关文章:

  • 防火墙在OSI模型中的层级工作(2025)
  • 【Node.js 深度解析】npm install 遭遇:npm ERR! code CERT_HAS_EXPIRED 错误的终极解决方案
  • PCI DSS培训记录
  • graphviz, dot, Error: lost rA sA edge; 独立的模块
  • Spring Boot + MyBatis-Plus 读写分离与多 Slave 负载均衡示例
  • 从0开始学习R语言--Day16--倾向得分匹配
  • 鸿蒙UI开发——组件的自适应拉伸
  • 后端解决跨域问题的三种方案:注解配置 vs 全局配置 vs 过滤器配置(附完整代码详解)
  • Hadoop HDFS 体系结构与文件读写流程剖析
  • 解决 idea提示`SQL dialect is not configured` 问题
  • 学习threejs,交互式神经网络可视化
  • RAG入门 - Reader(2)
  • Web3如何重塑数据隐私的未来
  • JsonCpp 库如何集成到Visual studio
  • 【Visual Studio 2022】卸载安装,ASP.NET
  • 动态规划十大经典题型状态转移、模版等整理(包括leetcode、洛谷题号)
  • 基于LLaMA-Factory和Easy Dataset的Qwen3微调实战:从数据准备到LoRA微调推理评估的全流程指南
  • 每日算法刷题Day21 6.3:leetcode二分答案2道题,用时1h20min(有点慢)
  • 关于Qt项目配置,项目编译生成的库文件路径详解
  • Git 常用命令 - 服务器用
  • LangChain系列之LangChain4j集成Spring Bot
  • es 的字段类型(text和keyword)
  • https(SSL)证书危机和可行的解决方案
  • 软考 系统架构设计师系列知识点之杂项集萃(79)
  • (10)Fiddler抓包-Fiddler如何设置捕获Firefox浏览器的Https会话
  • 进阶配置与优化:配置 HTTPS 以确保数据安全传输
  • HttpServletResponse 对象用来做什么?
  • Linux 下 ChromeDriver 安装
  • React前端框架
  • isp调试 blend模式指什么