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

C++ 右值 左值引用

一.什么是左值引用 右值引用

1.左值引用

左值是一个表示数据的表达式(如变量名或解引用的指针),我们可以获取它的地址+可以对它赋值。定义时const修饰符后的左值,不能给他赋值,但是可以取它的地址。左值引用就是给左值的引用,给左值取别名。

int main()
{
// 以下的p、b、c、*p都是左值
int* p = new int(0);
int b = 1;
const int c = 2;
// 以下几个是对上面左值的左值引用
int*& rp = p;
int& rb = b;
const int& rc = c;
int& pvalue = *p;
return 0;
}

2.右值引用

右值也是一个表示数据的表达式,如:字面常量、表达式返回值,函数返回值(这个不能是左值引用返回)等等,右值可以出现在赋值符号的右边,但是不能出现出现在赋值符号的左边,右值不能取地址。右值引用就是对右值的引用,给右值取别名。

int main()
{
double x = 1.1, y = 2.2;
// 以下几个都是常见的右值
10;
x + y;
fmin(x, y);
// 以下几个都是对右值的右值引用
int&& rr1 = 10;                 //常量
double&& rr2 = x + y;           //临时变量
double&& rr3 = fmin(x, y);      //临时变量
// 这里编译会报错:error C2106: “=”: 左操作数必须为左值
10 = 1;
x + y = 1;
fmin(x, y) = 1;
return 0;
}

区分左值右值关键就看能否取地址,左值可以取地址,右值不能取地址。

注意:
int&& rr1=10 10是常量是右值,那rr1是右值吗?

rr1是左值,因为rr1要有空间存储10,所以有地址。可以对它本身进行修改,但有const 修饰的,const int&& rr1不能。

左值/右值引用引用的一定是左值/右值吗?

1.左值

1. 左值引用只能引用左值,不能引用右值。
2. 但是const左值引用既可引用左值,也可引用右值。

int main()
{// 左值引用只能引用左值,不能引用右值。int a = 10;int& ra1 = a;   // ra为a的别名//int& ra2 = 10;   // 编译失败,因为10是右值// const左值引用既可引用左值,也可引用右值。const int& ra3 = 10;const int& ra4 = a;return 0;
}

2.右值

1. 右值引用只能右值,不能引用左值。
2. 但是右值引用可以move以后的左值。(move原理和强转一致,只是把左值属性转换成右值,在底层实现时左值右值没有区别,只是为了编译通过)

int main()
{// 右值引用只能右值,不能引用左值。int&& r1 = 10;// error C2440: “初始化”: 无法从“int”转换为“int &&”// message : 无法将左值绑定到右值引用int a = 10;//int&& r2 = a;// 右值引用可以引用move以后的左值int&& r3 = std::move(a);return 0;
}

二.左值引用使用场景

当我们进行传参,函数返回值时 直接引用就可以减少拷贝,提高效率。

void func1(bit::string s)
{}
void func2(const bit::string& s)
{}
int main()
{bit::string s1("hello world");// func1和func2的调用我们可以看到左值引用做参数减少了拷贝,提高效率的使用场景和价值func1(s1);func2(s1);// string operator+=(char ch) 传值返回存在深拷贝// string& operator+=(char ch) 传左值引用没有拷贝提高了效率s1 += '!';return 0;
}

左值引用的短板:

当函数返回值是一个局部变量,出了作用域就会销毁,这样返回的左值引用就没有意义了,只能进行拷贝 传值返回。

string operator+(const string& s, char ch)
{string ret(s);ret.push_back(ch);return ret;
}

ret左值出了作用域就会销毁

三.右值引用使用场景

在C++11前都是在mian()函数中定义ret再传给operator+(),延长生命周期。

之后引出了右值引用和移动语义来解决。

1.移动语义

将一个对象的资源转到另一个对象上。

1.移动构造

移动构造和拷贝构造区别在于,移动构造只能接受右值/move(左值) 。而拷贝构造左值右值(const)都可以接收。 当我们传右值编译器会优先匹配更符合的 移动构造。

我们知道to_string中创建的str左值,但马上被销毁,编译器会自动识别为右值,属于将亡值。这样就可以走移动构造转移资源 减少拷贝。

2.移动赋值

用常量1234初始化会调用移动构造,to_string返回值再通过移动复制将资源转移到ret1上。

// 移动赋值
string& operator=(string&& s)
{
cout << "string& operator=(string&& s) -- 移动语义" << endl;
swap(s);
return *this;
}
int main()
{
bit::string ret1;
ret1 = bit::to_string(1234);
return 0;
}
// 运行结果:
// string(string&& s) -- 移动语义
// string& operator=(string&& s) -- 移动语义

四.完美转发

万能引用

首先我们要了解什么是万能引用。

确定类型的 && 表示右值引用(比如:int&& ,string&&),
函数模板中的 && 不表示右值引用,而是万能引用模板类型必须通过推断才能确定,其接收左值后会被推导为左值引用,接收右值后会被推导为右值引用

template<typename T>
void f(T&& t)  // 万能引用
{//...
}int main()
{int a = 5;  // int 左值f(a);  // 传参后int&const string s("hello");  // const string 左值f(s);  // 传参后const string&f(to_string(1234));  // 右值 传参后 string&&return 0;
}

注意区分右值引用和万能引用:下面的函数的 T&& 并不是万能引用,因为 T 的类型在模板实例化时已经确定。

template<class T>
class A
{void func(T&& a){}
};

for_ward()

为什么都调用的左值引用呢?

因为在传参时右值变为了左值,导致调用Fun()函数时t参数的属性永远是左值。

这时候就需要forward<T>()完美转发,保持参数属性,左值还是左值,右值还是右值。

相关文章:

C++ 右值 左值引用

一.什么是左值引用 右值引用 1.左值引用 左值是一个表示数据的表达式(如变量名或解引用的指针)&#xff0c;我们可以获取它的地址可以对它赋值。定义时const修饰符后的左值&#xff0c;不能给他赋值&#xff0c;但是可以取它的地址。左值引用就是给左值的引用&#xff0c;给左…...

「JavaEE」Spring IoC 1:Bean 的存储

&#x1f387;个人主页 &#x1f387;所属专栏&#xff1a;Spring &#x1f387;欢迎点赞收藏加关注哦&#xff01; IoC 简介 IoC 全称 Inversion of Control&#xff0c;即控制反转 控制反转是指控制权反转&#xff1a;获得依赖对象的过程被反转了 传统开发模式中&…...

springBoot快速搭建WebSocket

添加依赖 在pom.xml中加入WebSocket相关依赖&#xff1a; <dependencies><!-- websocket --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>…...

掌控授权的艺术:Laravel自定义策略模式深度解析

掌控授权的艺术&#xff1a;Laravel自定义策略模式深度解析 在现代Web应用开发中&#xff0c;权限管理是核心功能之一。Laravel框架通过其策略模式提供了一种优雅的方式来处理授权问题。然而&#xff0c;随着应用的复杂性增加&#xff0c;内置的策略可能不足以满足所有需求。这…...

Git操作指令(随时更新)

Git操作指令 一、安装git 1、设置配置信息&#xff1a; # global全局配置 git config --global user.name "Your username" git config --global user.email "Your email"# 显示颜色 git config --global color.ui true# 配置别名&#xff0c;各种指令都…...

SpringSecurity自定义登录方式

自定义登录&#xff1a; 定义Token定义Filter定义Provider配置类中定义登录的接口 自定义AuthenticationToken public class EmailAuthenticationToken extends UsernamePasswordAuthenticationToken{public EmailAuthenticationToken(Object principal, Object credentials) …...

黑神话悟空是什么游戏 黑神话悟空配置要求 黑神话悟空好玩吗值得买吗 黑神话悟空苹果电脑可以玩吗

《黑神话&#xff1a;悟空》的类型定义是一款单机动作角色扮演游戏&#xff0c;但实际体验后会发现&#xff0c;游戏在很多设计上采用了「魂like」作品的常见元素。根据个人上手试玩&#xff0c;《黑神话&#xff1a;悟空》的推进节奏比较接近魂类游戏&#xff0c;Boss战也更像…...

深入浅出消息队列----【延迟消息的实现原理】

深入浅出消息队列----【延迟消息的实现原理】 粗说 RocketMQ 的设计细说 RocketMQ 的设计这样实现是否有什么问题&#xff1f; 本文仅是文章笔记&#xff0c;整理了原文章中重要的知识点、记录了个人的看法 文章来源&#xff1a;编程导航-鱼皮【yes哥深入浅出消息队列专栏】 粗…...

npm提示 certificate has expired 证书已过期 已解决

在用npm新建项目时&#xff0c;突然发现报错提示 : certificate has expired 证书已过期 了解一下&#xff0c;在网络通信中&#xff0c;HTTPS 是一种通过 SSL/TLS 加密的安全 HTTP 通信协议。证书在 HTTPS 中扮演着至关重要的角色&#xff0c;用于验证服务器身份并加密数据传输…...

KEIL如何封装文件成lib

一、为什么要封装文件成LIB 提高编译效率 如果一份文件已经在整个工程中发挥出了我们期待的作用&#xff0c;现在想要将其封装成库&#xff0c;则可以在已经成型的工程文件中将不需要编译的文件从工程全部移出掉&#xff0c;只留下我们需要封装的文件&#xff0c;这样就可以提…...

【python】OpenCV—Faster Video File FPS

文章目录 1、需求描述2、正常方法 cv2.read3、加速方法 imutils.video.FileVideoStream4、涉及到的核心库函数4.1、imutils.video.FPS4.2、imutils.video.FileVideoStream 5、参考 1、需求描述 使用线程和队列数据结构将视频文件的 FPS 速率提高 &#xff01; 我们的目标是将…...

JavaScript变量的类型转换

类型转换分为两种:显示类型转换、隐式类型转换 1.显示类型转换 String()Number()Boolean()toString()parseInt(string)parseFloat(string)2.隐式类型转换 (1)isNaN () 判断指定的参数是否为 NaN(非数字类型),返回结果为 Boolean 类型。也就是说:任何不能被转换为数值的…...

如何申请免费SSL证书以消除访问网站显示连接不安全提醒

在当今互联网时代&#xff0c;网络安全已成为一个不可忽视的问题。当用户浏览一些网站时&#xff0c;有时会看到浏览器地址栏出现“不安全”的提示&#xff0c;这意味着该网站没有安装SSL证书&#xff0c;数据传输可能存在风险。那么&#xff0c;如何消除这种不安全提醒&#x…...

关于P2P(点对点)

P2P 是一种客户端与客户端之间&#xff0c;点对点连接的技术&#xff0c;在早前的客户端都是公网IP&#xff0c;没有NAT的情况下&#xff0c;P2P是较为容易实现的。 但现在的P2P&#xff0c;实现上面会略微有一些复杂&#xff1a;需要采取UDP打洞的技术&#xff0c;但UDP打出来…...

前端怎么本地起一个服务查看本地文件

1.安装拓展 安装 Live Server拓展 2.创建一个html文件 3.在html文件中右键选择 Open with Live Server 4.浏览器打开运行的地址&#xff0c;并去除路径&#xff0c;例如:http://127.0.0.1:5500/...

建造者模式(Builder Pattern)

建造者模式&#xff08;Builder Pattern&#xff09;是一种创建型设计模式&#xff0c;它主要用于将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。这种设计模式的核心思想是将一个复杂对象的构建分解成多个相对简单的步骤&#xff0c;并…...

【MySQL】索引 【下】{聚簇索引VS非聚簇索引/创建主键索引/全文索引的创建/索引创建原则}

文章目录 1.聚簇索引 VS 非聚簇索引经典问题 2.索引操作创建主键索引唯一索引的创建普通索引的创建全文索引的创建查询索引删除索引索引创建原则 1.聚簇索引 VS 非聚簇索引 之前介绍的将所有的数据都放在叶子节点的这种存储引擎对应的就是 InnoDB 默认存储表数据的存储结构。 …...

论文快过(图像配准|Coarse_LoFTR_TRT)|适用于移动端的LoFTR算法的改进分析 1060显卡上45fps

项目地址&#xff1a;https://github.com/Kolkir/Coarse_LoFTR_TRT 创建时间&#xff1a;2022年 相关训练数据&#xff1a;BlendedMVS LoFTR [19]是一种有效的深度学习方法&#xff0c;可以在图像对上寻找合适的局部特征匹配。本文报道了该方法在低计算性能和有限内存条件下的…...

免费发送邮件两种接口方式:SMTP和邮件API

SMTP与邮件API在处理大批量邮件发送时&#xff0c;哪个更稳定&#xff1f; 在现代信息化的社会中&#xff0c;邮件已成为不可或缺的沟通工具。无论是个人还是企业&#xff0c;发送邮件都是日常工作的一部分。AokSend将详细介绍两种常用的免费发送邮件接口方式&#xff1a;SMTP…...

大模型日报 2024-07-30

大模型日报 2024-07-30 大模型资讯 开源AI性能逼近专有领袖&#xff0c;最新基准测试揭示 摘要: Galileo最新的幻觉指数显示&#xff0c;开源AI模型的性能正在迅速逼近专有巨头。这一发现表明&#xff0c;开源AI在技术进步和性能提升方面取得了显著进展&#xff0c;缩小了与专有…...

OWL ADVENTURE应用场景解析:如何用AI助手提升工作效率

OWL ADVENTURE应用场景解析&#xff1a;如何用AI助手提升工作效率 1. 为什么选择OWL ADVENTURE作为AI助手 在当今快节奏的工作环境中&#xff0c;我们每天都要处理大量视觉信息——从产品图片到数据图表&#xff0c;从设计稿到文档扫描件。传统的工作流程往往需要人工逐一查看…...

别再被MPU6050的偏航角坑了!手把手教你用MPU9250(或外接HMC5883L磁力计)彻底解决零飘问题

彻底解决MPU6050偏航角零飘&#xff1a;硬件升级与磁力计融合实战指南 在无人机、平衡车和机器人姿态控制领域&#xff0c;MPU6050曾是许多开发者的首选惯性测量单元(IMU)。这款经典的六轴传感器以低廉的价格和稳定的性能赢得了市场&#xff0c;但它的一个致命缺陷让无数工程师…...

Anything to RealCharacters 2.5D转真人引擎效果可视化:预处理前后对比与输出质量评估

Anything to RealCharacters 2.5D转真人引擎效果可视化&#xff1a;预处理前后对比与输出质量评估 你是否曾想过&#xff0c;将心爱的动漫角色、游戏立绘或者卡通头像&#xff0c;一键变成一张以假乱真的真人照片&#xff1f;这听起来像是魔法&#xff0c;但现在&#xff0c;借…...

别再纠结硬件滚动了!用Arduino+SSD1306库实现超长文本的软件滚动显示(附完整代码)

ArduinoSSD1306实现超长文本流畅滚动的终极方案 当你在创客项目中需要显示超出屏幕宽度的日志数据或长消息时&#xff0c;硬件滚动的局限性就会暴露无遗。我曾在一个环境监测项目中遇到这个问题——传感器数据经常超过OLED屏幕的16字符显示限制&#xff0c;硬件滚动方案直接截断…...

LLM大模型开发实战:6个爆款开源项目,小白也能轻松入门!

本文介绍了6个GitHub上的热门LLM&#xff08;大型语言模型&#xff09;开源项目&#xff0c;包括Datawhale的"LLM-Universe"和"LLM-Cookbook"、微软的"Generative AI for Beginners"、mlabonne的"LLM-Course"、liguodongiot的"LL…...

Spring Boot项目实战:手把手教你配置Google Play订阅与Pub/Sub回调(含完整代码)

Spring Boot实战&#xff1a;构建高可靠Google Play订阅与Pub/Sub回调系统 在移动应用商业化路径中&#xff0c;应用内订阅已成为数字服务持续变现的核心模式。根据Statista数据&#xff0c;2023年全球应用订阅收入达到380亿美元&#xff0c;其中Google Play贡献了超过34%的份额…...

旧设备优化指南:iPhone 6s系统降级与性能提升全攻略

旧设备优化指南&#xff1a;iPhone 6s系统降级与性能提升全攻略 【免费下载链接】Legacy-iOS-Kit An all-in-one tool to downgrade/restore, save SHSH blobs, and jailbreak legacy iOS devices 项目地址: https://gitcode.com/gh_mirrors/le/Legacy-iOS-Kit 当你的iP…...

告别‘Illegal instruction’:为老旧ARM芯片(如鲲鹏920)定制MongoDB 4.4.9的完整避坑流程

为老旧ARM芯片定制MongoDB 4.4.9的完整避坑指南 当你在国产ARM服务器上部署MongoDB时&#xff0c;是否遇到过Illegal instruction错误&#xff1f;这个问题往往源于硬件与软件版本之间的指令集不匹配。本文将带你深入理解ARM架构的版本差异&#xff0c;并提供一套完整的解决方案…...

YOLOv5实战:如何用Python手写IoU计算函数提升目标检测精度

YOLOv5实战&#xff1a;手写IoU计算函数提升目标检测精度的Python实现 在目标检测任务中&#xff0c;边界框的定位精度直接影响模型性能。IoU&#xff08;Intersection over Union&#xff09;作为衡量预测框与真实框重合度的核心指标&#xff0c;其计算准确性对模型优化至关重…...

Wan2.2-I2V-A14B生产环境部署:Nginx反向代理与Docker Compose编排

Wan2.2-I2V-A14B生产环境部署&#xff1a;Nginx反向代理与Docker Compose编排 1. 部署目标与前置准备 在开始之前&#xff0c;我们先明确这次部署要实现的目标&#xff1a;通过Docker Compose编排Wan2.2-I2V-A14B模型服务及其依赖组件&#xff0c;使用Nginx作为反向代理&…...