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

C++编程之 万能引用

万能引用是一种可以同时接受左值或右值的引用,它的形式是T&&,其中T是一个模板参数。万能引用不是C++的一个新特性,而是利用了模板类型推导引用折叠的规则来实现的功能。

模板类型推导

模板类型推导是指在调用一个模板函数时,编译器会根据传入的实参来推导出模板参数的类型。例如:

template<class T>
void f(T t) {}int x = 10; // x 是左值
f(x); // 调用f时,T被推导为int(注意而不是int&)
f(20); // 调用f时,T被推导为int

之所以调用f(x)时,T被推导为int,这是因为如果实参是一个左值,那么它会被当作一个右值来处理,除非模板参数的形式是T&或者T&&。例如:

template<class T>
void h(T t) {}template<class T>
void i(T& t) {}template<class T>
void j(T&& t) {}int x = 10; // x 是左值
h(x); // 调用h时,T被推导为int
i(x); // 调用i时,T被推导为int
j(x); // 调用j时,T被推导为int&

你可以看到,在调用h和i时,T都被推导为int,而在调用j时,T才被推导为int&。这是因为在j的模板参数中使用了&&符号,这样就触发了万能引用的机制。

当模板参数的形式为T&的时候:

template<class T>
void k(T& t) {}int x = 10; // x 是左值
k(x); // 调用k时,T被推导为int
k(20); // 调用k时,编译错误,因为不能把右值绑定到非常量左值引用上

你可以看到,在调用k时,如果传入一个右值,就会发生编译错误。这是因为右值是临时的,不能被修改或者延长其生命周期。如果想要让模板函数接受右值,可以使用常量左值引用或者右值引用作为模板参数的形式。

引用折叠

引用折叠是指在定义一个引用类型时,如果它本身就是一个引用类型,那么会发生如下的转换:

  • 左值引用& + 左值引用& = 左值引用&
  • 右值引用&& + 右值引用&& = 右值引用&&
  • 左值引用& + 右值引用&& = 左值引用&
  • 右值引用&& + 左值引用& = 左值引用&

例如:

int x = 10; // x 是左值
int &r1 = x; // r1 是左值引用
int &&r2 = 20; // r2 是右值引用// 引入了两个别名类型:
using LRef = int &;
using RRef = int &&;LRef &r3 = r1; // r3 的类型是 LRef &,即 int & &,经过折叠后变为 int &
RRef &&r4 = r2; // r4 的类型是 RRef &&,即 int && &&,经过折叠后变为 int &&
LRef &r5 = r2; // r5 的类型是 LRef &,即 int & &&,经过折叠后变为 int &
RRef &&r6 = r1; // r6 的类型是 RRef &&,即 int && &,经过折叠后变为 int &

结合这两个规则,我们就可以理解万能引用的工作原理。例如:

template<class T>
void g(T&& t) {}int x = 10; // x 是左值
g(x); // 调用g时,T被推导为int&(注意不是int),因此t的类型是int& &&// 经过折叠后变为int&(左值)
g(20); // 调用g时,T被推导为int(注意不是int&),因此t的类型是int &&// 经过折叠后仍然是int&&(右值)

你可以看到,在调用g时,t既可以绑定到左值上也可以绑定到右值上,并且保持了原来实参的属性。这就实现了万能引用。

相关文章:

C++编程之 万能引用

万能引用是一种可以同时接受左值或右值的引用&#xff0c;它的形式是T&&&#xff0c;其中T是一个模板参数。万能引用不是C的一个新特性&#xff0c;而是利用了模板类型推导和引用折叠的规则来实现的功能。 模板类型推导 模板类型推导是指在调用一个模板函数时&#x…...

【JavaScript速成之路】JavaScript内置对象--数组对象

&#x1f4c3;个人主页&#xff1a;「小杨」的csdn博客 &#x1f525;系列专栏&#xff1a;【JavaScript速成之路】 &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; 文章目录前言数组对象1&#xff0c;数组类型检测2&#xff0c;数组元素增删3&#xff0c;…...

【华为机试真题详解 Python实现】最差产品奖【2023 Q1 | 100分】

文章目录 前言题目描述输入描述输出描述示例 1题目解析参考代码前言 《华为机试真题详解》专栏含牛客网华为专栏、华为面经试题、华为OD机试真题。 如果您在准备华为的面试,期间有想了解的可以私信我,我会尽可能帮您解答,也可以给您一些建议! 本文解法非最优解(即非性能…...

[算法] 二分查找

package com.guigu.search;import java.util.ArrayList; import java.util.Arrays;/*** author: guorui fu* versiion: 1.0* 二分查找 直接适用于已经排序完成的数组*/ public class BinarySearch {public static void main(String[] args) {int arr[] {1,8,8,89,101,1234};Ar…...

HTML面经

1.src与href的区别 src用于替换当前元素&#xff0c;如script标签&#xff0c;img标签等。当html解析到这些标签时&#xff0c;会暂停解析&#xff0c;将指定的资源下载下来&#xff0c;嵌入到所在位置内。href的话则是一个当前页面与引用资源之间的链接&#xff0c;如link标签…...

我的十年编程路 2021年篇

慢慢地&#xff0c;时光走过了8个年头&#xff0c;来到2021年。 站在2021年&#xff0c;回望8年的过往&#xff0c;没有大的起伏和波澜。或许是上天的眷顾&#xff0c;我的事业发展一直都很顺利。当然&#xff0c;弯路也走过一些&#xff0c;而且工作其实挺辗转的&#xff0c;…...

ElasticSearch 8 学习笔记总结(七)

感觉这些东西没必要认真学&#xff0c;了解一下&#xff0c;工作用到再学。 文章目录一、ES8 EQL 介绍二、ES8 EQL基本操作 与 安全检测三、ES SQL操作四、ES SQL与DSL的关系五、ES 常用的SQL操作六、ES datagrip配置ES七、ES8 自然语言处理 NLP八、ES8 性能优化 之 缓存九、ES…...

【云原生】Docker 网络模式详解、容器间网络通信

当项目大规模使用 Docker 时&#xff0c;容器通信的问题也就产生了。要解决容器通信问题&#xff0c;必须先了解很多关于网络的知识。Docker 作为目前最火的轻量级容器技术&#xff0c;有很多令人称道的功能&#xff0c;也有着很多不完善的地方&#xff0c;网络方面就是 Docker…...

Java开发 - 布隆过滤器初体验

目录 前言 布隆过滤器 什么是布隆过滤器 布隆过滤器的作用 布隆过滤器原理 怎么设计布隆过滤器 布隆过滤器使用案例 安装布隆过滤器 添加依赖 添加配置 添加工具类 添加测试代码 简单测试 特别提醒​​​​​​​ 结语 前言 前面三篇&#xff0c;已经把消息队列…...

【计算机组成原理 - 第一章】计算机系统概论(完结)

本章参考王道考研相关课程&#xff1a; 【2021版】1.2.1_计算机硬件的基本组成_哔哩哔哩_bilibili 【2021版】1.2.2_认识各个硬件部件_哔哩哔哩_bilibili 【2021版】1.2.3_计算机系统的层次结构_哔哩哔哩_bilibili 【2021版】1.3_计算机的性能指标_哔哩哔哩_bilibili 目录 一、…...

C++类与对象(下)【详析】

类与对象&#xff08;下&#xff09; 目录类与对象&#xff08;下&#xff09;一、再谈构造函数1.构造函数体赋值2.初始化列表定义&#xff1a;注意点&#xff1a;总结&#xff1a;3.explicit关键字引入&#xff1a;explicit&#xff1a;二、 static成员回顾&#xff1a;static…...

exe反编译为.py文件

介绍公司以前的一个exe包&#xff0c;我们需要查看里面python源码&#xff0c;但是以前的py源码文件找不到&#xff0c;所以只能反编译&#xff0c;介绍一下反编译的过程。首先准备&#xff1a;pyinstxtractor.py这个文件&#xff0c;网上很多&#xff0c;自己下载准备查看二进…...

38 openEuler搭建FTP服务器-FTP总体介绍

文章目录38 openEuler搭建FTP服务器-FTP总体介绍38.1 FTP简介38.2 FTP使用到的端口38.3 vsftpd简介38 openEuler搭建FTP服务器-FTP总体介绍 38.1 FTP简介 FTP&#xff08;File Transfer Protocol&#xff09;即文件传输协议&#xff0c;是互联网最早的传输协议之一&#xff0…...

三天吃透操作系统面试八股文

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点&#xff0c;欢迎star~ Github地址&#xff1a;https://github.com/…...

vue后台管理系统——添加i18n国际化功能——技能提升

昨天在写后台管理系统时&#xff0c;遇到一个需求就是需要实现国际化功能。 antd和element-ui这两个框架其实都是有国际化的。 具体展示形式就是如下&#xff1a; 点击右上角头部的语言&#xff0c;切换语言&#xff0c;然后整个系统的文字都改变成对应的语言展示。 切换成…...

理清gcc、g++、libc、glibc、libstdc++的关系

0 理清gcc、g++、libc、glibc、libstdc++的关系 0.1 $ dpkg -L libc6 $ dpkg -L libc6 /lib/x86_64-linux-gnu /lib/x86_64-linux-gnu/ld-2.31.so /lib/x86_64-linux-gnu/libBrokenLocale-2.31.so /lib/x86_64-linux-gnu/libSegFault.so /lib/x86_64-linux-gnu/libanl-2.31.s…...

一、快速入门 MongoDB 数据库

文章目录一、NoSQL 是什么1.1 NoSQL 简史1.2 NoSQL 的种类及其特性1.3 NoSQL 特点1.4 NoSQL 的优缺点1.5 NoSQL 与 SQL 数据库的比较二、MongoDB 基础知识2.1 MongoDB 是什么2.2 MongoDB 的体系结构2.3 MongoDB 的特点2.4 MongoDB 键特性2.5 MongoDB 的核心服务和工具2.6 Mongo…...

PMP第一章到第三章重要知识点

第1章引论 1.1指南概述和目的 PMBOK指南收录项目管理知识体系中被普遍认可为“良好实践”的那一部分&#xff1a; “普遍认可”&#xff1a;大多数时候适用于大多数项目&#xff0c;获得一致认可。 “良好实践”&#xff1a;能提高很多项目成功的可能性。 全球项目管理业界…...

【事务与锁】当Transactional遇上synchronized

事务与锁 - Transactional与Synchronize&#x1f970;前言问题回放问题一1、代码与结果复现2、原因分析3、解决方法问题二1、问题复现2、原因分析事务Transactional与锁synchronized1、synchronized与Transactional区别2、可能带来的问题3、针对问题二的解决前言 最近工作中遇…...

Pytorch模型转TensorRT步骤

Pytorch模型转TensorRT步骤 yolov5转TRT 流程 当前项目基于yolov5-6.0版本&#xff0c;如果使用其他版本代码请参考 https://github.com/wang-xinyu/tensorrtx/tree/master/yolov5 获取转换项目&#xff1a; git clone https://github.com/wang-xinyu/tensorrtx.git git …...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...

沙箱虚拟化技术虚拟机容器之间的关系详解

问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西&#xff0c;但是如果把三者放在一起&#xff0c;它们之间到底什么关系&#xff1f;又有什么联系呢&#xff1f;我不是很明白&#xff01;&#xff01;&#xff01; 就比如说&#xff1a; 沙箱&#…...