左值与右值

左值与右值的概念

可以被取地址的值为左值(left value,简称lvalue),否则为右值(right value,简称rvalue)。
常见的左值、右值例子:

// >>>>>>> 左值
// a, p, str, str[0]等均为左值
int a = 10;
int* p = &a;
string str("hello");
str[0]// >>>>>>> 右值
// 匿名对象,临时表达式,常量10、“world”,均为右值
string("world")
x + y
10

初步认识左值和右值时,可以理解记忆为左值存储在内存中,具有“身份”,生命周期长。右值存储在寄存器中,大多为临时变量,生命周期短。

但实际上,不完全是这样:可能存在被编译器优化为存储于寄存器的左值(临时变量),也有占用空间较大,需要存储于内存的临时副本(如复杂匿名对象)。初步认识时可以帮助理解move()将左值转换为右值的行为,类似汇编中的mov命令。

右值引用

语法为使用&&,例如:

int&& a;
char&& b;

特性:

  1. 左值引用不能直接引用右值,除非加const限定;右值引用也不能直接引用左值,需要使用move()处理左值。
  2. 右值引用本身是一个左值。

移动构造

语法规则

class class_name {
public:class_name(class_name&& t) {::swap(t, t.array);    // 交换资源}private:int* array;
}

意义

右值引用的概念与移动构造等特性密切相关,C++11提供了一种提高程序效率的方式,通过交换临时资源的指针代替拷贝。

对于下面这一段程序:

string func() {string tmp("1111111111111");return tmp;
}int main() {string str = func();...
}

取决于编译器的不同优化方式,C++98标准下,实际的程序会有三种行为:

  1. 在func内调用构造函数得到tmp,传值返回时调用构造,得到临时对象,然后拷贝赋值给str;
  2. 省略临时对象的构造,直接将tmp拷贝赋值给str;
  3. 省略tmp的构造,直接用"1111111111111"构造str;

移动构造出现后就能够替代拷贝构造,降低拷贝时的资源消耗。因为对于整个程序来说,tmp的存在只是暂时的【实际会被视为将亡值】,其资源被转移给str也无所谓,所以不用进行拷贝,直接交换资源,就能达成相同的效果。

引用折叠

基本规则

类似“&”与运算,要右值引用的右值引用最终才是右值引用。

typedef int& lref
typedef int&& rref
lref&  a  -> a的类型为int&
lref&& b  -> b的类型为int&
rref&  c  -> c的类型为int&
rref&& d  -> d的类型为int&&

TIP: 不能直接写int& &&int& &,即不能直接对引用再做引用,必须通过typedef自定义类型才可以,否则会语法报错。

完美引用

借用“引用折叠”的规则,可以统一模版的写法,使得最终的类型完全由实例化时的类型决定。万能模版写法:

tempate<class T>
void func(T&& a) {...
}func<int&> f1(num1)  // 最终a要求为一个左值,因此num1需要是左值
func<int&&> f2(num2) // 最终a要求为一个右值,因此num2需要是右值

完美转发

forward<typename>(arg);

为避免右值被右值引用后变为左值,调用该函数,可以保持参数arg的原始属性。

例子:

void overload(int&& rv) { std::cout << "rv " std::endl; }
void overload(int& lv) { std::cout << "lv" std::endl; }void func(int&& v) {overload(v);overload(std::forwad<int>(v));
}
  • 当调用func时输入左值,将会得到输出:lv lv
  • 当调用func时输入右值,将会输出:lv rv

意义

完美引用结合完美转发,可以运用在模版的嵌套场景,可以有效避免代码冗余,同时提高代码效率。

Lambda表达式

本质

lambda表达式的本质是一个匿名函数对象,可以直接定义在函数内部。

语法

// [capture list] (parameters) -> retrun type (function body)int main() {auto test1 = [](int a) -> void {cout << a << endl;return 0;}test1(1);return 0;
}
  1. 捕捉列表(capture list)不能省略
  2. 如果参数为空,则可以省略
  3. 即使有返回值,返回值类型也可以省略,将会由返回对象自动推导
  4. 函数体不能省略(必然的)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/95386.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/95386.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/95386.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

因为对象装箱拆箱导致的空指针异常

今天业务突然提了个事件单&#xff0c;客户添加承租人一直报错&#xff0c;但是很奇怪&#xff0c;报错信息是空的二话不说&#xff0c;先跟API组要了接口和参数&#xff0c;然后看日志然鹅&#xff0c;这个接口并没有打印日志&#xff0c;只有一个e.printStackTrace()然后静下…

Rust 在 Windows 环境下交叉编译其他操作系统可执行文件的详细指南

前言&#xff1a;为什么需要交叉编译&#xff1f; 想象一下这样的场景&#xff1a;你在 Windows 电脑上开发了一个 Rust 程序&#xff0c;希望它能在 Linux 服务器上运行&#xff0c;或者在朋友的 macOS 电脑上测试 —— 总不能为了编译不同系统的版本&#xff0c;专门买一台 …

Ubuntu系统配置镜像源

要修改的文件 /etc/apt/sources.list操作步骤 1. 备份原文件 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak2. 编辑文件 sudo nano /etc/apt/sources.list3. 清空文件内容&#xff0c;填入以下内容 先获取Ubuntu版本代号&#xff1a; lsb_release -cs然后根据版本填…

【Spring Cloud Alibaba】Sentinel(一)

【Spring Cloud Alibaba】Sentinel&#xff08;一&#xff09;1. 简介2. 服务雪崩1. 简介 Sentinel 是阿里巴巴开源的分布式系统的流量防护组件&#xff0c;主要用来做流量控制、熔断降级、系统保护。它的定位类似于 Hystrix&#xff0c;但更侧重在 流量治理 上。目前在微服务…

Delphi 5 操作Word表格选区问题解析

在 Delphi 5 中操作 Word 时&#xff0c;您遇到的 Selection.MoveDown 方法选中整行而不是仅移动一行的原因与 Word 的选择机制和单元格内部结构有关。以下是详细解释和解决方案&#xff1a;问题分析单元格的选区范围&#xff1a;当使用 .Cell(r, c).Select 选中单元格时&#…

小米fastboot不能被电脑识别但手机正常使用模式时能被电脑识别

小米手机USB连接电脑不识别解决方法 – MIUI历史版本 小米手机USB连接电脑不识别解决方法 问题经验 手机连接电脑通常会自动安装驱动&#xff0c;如果驱动安装失败或是电脑不能识别手机设备&#xff0c;可尝试下面方法。 1. 尝试换根 USB 数据线&#xff0c;最好是手机原…

Git 版本管理工具基本操作汇总—命令总结

通常&#xff0c;很多朋友在使用 Git 的时候都会直接用 IDE 中集成的插件或者自带的工具等来实现代码的拉取、提交、合并以及其他操作&#xff0c;当然这肯定也是可以的&#xff0c;但是长期这样子操作&#xff0c;我们就会忽略掉 Git 业务运行的底层逻辑。那么&#xff0c;我这…

自学嵌入式第三十三天:网络编程-UDP

一、OSI模型(open system interconnect)开放系统互联模型&#xff0c;分为7层应用层&#xff1a;为网络用户提供各种服务&#xff0c;例如电子邮件、文件传输等&#xff1b;表示层&#xff1a;为不同主机间的通信提供统一的数据表示形式。加密解密&#xff0c;压缩&#xff1b;…

A*(Astar)算法详解与应用

算法背景A*&#xff08;A-Star&#xff09;算法是一种在图形平面上&#xff0c;有多个节点的路径中&#xff0c;求出最低通过成本的算法。其历史可以追溯到早期的图搜索算法&#xff0c;如Dijkstra算法和贪心最佳优先搜索&#xff08;Greedy Best-First Search&#xff09;。是…

word删除指定页面

常规程序因为wps的 .docx 文件是基于段落和节的结构&#xff0c;而不是“物理页”&#xff0c;所以无法直接按“第几页”删除在普通程序里面无法读取到他的页码&#xff0c;但是在宏编程里面他能读取到页码&#xff0c;我们就根据宏编程来这样删除。程序会自动打开选择要删除的…

RK3568平台开发系列讲解:瑞芯微平台4G模块篇移植

更多内容可以加入Linux系统知识库套餐(教程+视频+答疑) 🚀返回专栏总目录 文章目录 一、硬件图片 二、功能宏 三、增加PID/VID 支持 3.1、usb_device_id 结构体 3.2、usb_device_id 的注册 沉淀、分享、成长,让自己和他人都能有所收获!😄 一、硬件图片 目标: 结果…

面试 (一)

目录 1. HashMap是怎么解决冲突的 是用什么数据结构实现的 2. 为什么hashmap的初始长度为16 3. 多线程的核心参数 4. 多线程怎么工作的 5. CISCS是怎么实现的 6. JUC知识 7. C和java的区别 8. JVM底层编译的东西 9. 公平锁和非公平锁 10. 有人恶意攻击你的平台每秒发送…

计算机毕设选题:基于Python+Django的健康饮食管理系统设计【源码+文档+调试】

精彩专栏推荐订阅&#xff1a;在 下方专栏&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f496;&#x1f525;作者主页&#xff1a;计算机毕设木哥&#x1f525; &#x1f496; 文章目录 一、项目介绍二…

vscode terminal远程连接linux服务器GUI图形界面

看了很多教程&#xff0c;不清楚具体原理&#xff0c;但总之自己是摸索出来了&#xff1a; 1.下载vcxsrv&#xff0c;最后双击exe程序启动&#xff1a; 每一步的配置如下&#xff1a;2.修改配置 vscode中按下“ctrlshiftp”&#xff0c;然后输入“Remote-SSH: Open SSH Configu…

文档外发管理产品哪个品牌强?安全与效率双优产品推荐

在企业间协作日益加深的今天&#xff0c;企业对文档外发管理相关产品的安全性和效率要求越来越高。无论是日常业务协作&#xff0c;还是跨组织数据交换&#xff0c;如何确保文件在传输过程中不被泄露、篡改&#xff0c;同时又能高效流转&#xff0c;成为企业IT管理的重要课题。…

【教程】2025 IDEA 快速创建springboot(maven)项目

第一步&#xff1a;【新建】-【module】&#xff0c;左边选择springboot&#xff0c;右边填写相关信息。第二步&#xff1a;选择相关依赖。第三步&#xff1a;删掉一些无关的文件&#xff0c;保持项目简洁创建springboot项目已经结束了&#xff0c;下面是构建项目的架构以及环境…

【小白笔记】移动硬盘为什么总比电脑更容易满?

我明明只复制了10个G的文件&#xff0c;为什么我的移动硬盘就满了&#xff1f; 大家好&#xff0c;我是个刚入门的小白&#xff0c;最近遇到了一个让我百思不得其解的问题。我把电脑里的一些文件&#xff0c;总共加起来也就10个G左右&#xff0c;心想移动硬盘还有几十个G的空位…

单独一篇云原生介绍

云原生&#xff08;Cloud Native&#xff09;‌不是单一技术&#xff0c;而是一套构建和运行应用程序的完整方法论‌&#xff0c;旨在充分利用云计算的优势&#xff08;弹性、按需资源、分布式环境&#xff09;来构建‌高韧性、可扩展、易于管理的应用‌。它的核心思想是让应用…

Git如何查看提交行数与删除行数:统计代码贡献量的完整指南

Git如何查看提交行数与删除行数&#xff1a;统计代码贡献量的完整指南 在软件开发中&#xff0c;代码行数统计是衡量团队协作效率和项目进度的重要指标。通过Git的命令行工具&#xff0c;开发者可以轻松查看提交的代码行数、删除的代码行数以及净增行数。本文将详细介绍多种方…