左值、右值、左值引用和右值引用

左值、右值和左值引用,在C++11之前,我们都很熟悉也都很好理解。左值(LValue)就是有名字能够寻址的对象的值类型,右值就是在内存上没有名字的数值的值类型,左值引用就是指向左值的引用。

C++11引入了右值引用,从而可以去读写在内存上临时的右值(C++11之前可以使用const左值引用去指向右值来读右值的内容,但是无法修改所指向的右值内容)。

C++11之前,任何对象不是左值就是右值,那引入右值引用之后,右值引用到底是左值还是右值呢?考虑到右值引用在行为使用上与右值有相似的地方,但也有冲突的地方,具体细节可以参考C++标准文档(n3055)。于是C++标准委员会将原来非黑即白的左值和右值两种类型细分成了5种类别,其中一些类别还会有共同重叠的部分。这5种类别中最值的关注的就是新创建了XValue,C++标准规定将一个右值引用绑定到一个对象,这个行为或者说是这个表达式的结果就是XValue。可见,XValue的诞生就是为右值引用量身定制的。那XValue这个名字起源于eXpiring这个单词,其实也很好理解,当我们使用一个右值引用想要move一个临时对象的值时,这个临时对象的生命周期也就即将结束。

除了XValue,另外4中类型分别是LValue, GLValue,RValue和PRValue。LValue还是传统意义上的左值。GLValue是generalized LValue,它包括LValue和XValue。PRValue是pure RValue,虽然是新的类型,但它就是之前传统意义上的右值。RValue现在是一个统称,它包括PRValue和XValue。具体包含关系可以见下图:

需要注意的是,XValue它既是GLValue,也是RValue,所以这里是的关系。 

从图中可以看出,C++11之后,任何一个值,它肯定是LValue,XValue和PRValue中的一种。LValue和PRValue,我们都很好理解,那XValue到底会在哪些情况下出现用到呢?

C++标准规定了以下这些情况下的表达式的结果都是XValue:

  • 无论是显式还是隐式调用一个函数,只要函数返回值的类型是指向对象的右值引用,那么调用的结果就是XValue;
  • 将现有的对象转换成指向对象的右值引用,这个行为或者叫表达式的结果就是XValue;
  • 如果一个对象本身已经是XValue,那访问这个对象的非static的成员变量的表达式的结果就是XValue;
  • 如果一个对象本身已经是XValue,并且通过.*pointer-to-member的方式来访问成员变量,那这个表达式的结果就是XValue

总而言之,以上这些规则表明,有名字的(named)右值引用将会被视为左值没名字的(unnamed)右值引用将会被视为XValue。下面是这些规则的一个例子:

struct A {int m;
};A&& operator+(A, A);
A&& f();A a;
A&& ar = static_cast<A&&>(a);

表达式f(),表达式f().m,表达式static_cast<A&&>(a),表达式 a + a,以上这些表达式的结果都是XValue。表达式ar是一个左值,它的类型是A。根据文档中的解释,如果一个表达式是一个指向类型T的引用,那么这个表达式的类型将会调整为类型T。

上面的例子中static_cast<A&&>(a)是XValue,而std::move的实现正是使用了static_cast<X&&>:

template<typename T> struct remove_reference { typedef T type; };
template<typename T> struct remove_reference<T&> { typedef T type; };
template<typename T> struct remove_reference<T&&> { typedef T type; };template<typename T>
constexpr typename remove_reference<T>::type && move(T && arg) noexcept
{return static_cast<typename remove_reference<T>::type &&>(arg);
}

所以,std::move的返回值是一个XValue,而XValue也是一个右值,所以std::move的返回值也是一个右值,这也是为什么使用std::move可以触发调用move constructor/assignment,而不是调用copy constructor/assignment:

struct X
{std::string s_;X(){}X(const X & other) : s_{ other.s_ } {}X(X && other) noexcept : s_{ std::move(other.s_) } {}// other is an lvalue, and other.s_ is an lvalue too// use std::move to force using the move constructor for s_// don't use other.s_ after std::move (other than to destruct)
};int main()
{X a;X b = std::move(a);// a is an lvalue// use std::move to convert to a rvalue,// xvalue to be precise,// so that the move constructor for X is used// don't use a after std::move (other than to destruct)
}

参考资料:

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3055.pdf

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

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

相关文章

STM32 CubeMX ADC采集(HAL库)

STM32 CubeMX ADC采集&#xff08;HAL库&#xff09; STM32 CubeMX STM32 CubeMX ADC采集&#xff08;HAL库&#xff09;ADC介绍ADC主要特征最小识别电压值&#xff1a;2.4/4096≈0.6mv&#xff08;不考虑误差&#xff09;一、STM32 CubeMX设置二、代码部分三&#xff0c;单通道…

泛微OA e-office平台uploadify.php任意文件上传漏洞

泛微OA e-office平台uploadify.php任意文件上传漏洞复现 0x01 前言 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的…

玩转Linux—如何在Linux环境中部署MySQL、Redis和nginx

1、Linux常用命令 Linux学习之路&#xff1a; VMware虚拟机安装Linux系统(详解版) 查看当前文件目录&#xff1a;ls查看目录中文件详细信息&#xff1a;ll输出当前所处的目文件目录&#xff1a;pwdLinux查看当前IP地址&#xff1a;ifconfigWindows查看当前IP地址&#xff1…

基于SpringBoot的民宿在线预定平台

目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 民宿信息管理 民宿资讯管理 民宿分类管理 用户注册 民宿信息 我的订单 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实…

通过IP地址管理提升企业网络安全防御

在今天的数字时代&#xff0c;企业面临着越来越多的网络安全威胁。这些威胁可能来自各种来源&#xff0c;包括恶意软件、网络攻击和数据泄露。为了提高网络安全防御&#xff0c;企业需要采取一系列措施&#xff0c;其中IP地址管理是一个重要的方面 1. IP地址的基础知识 首先&a…

【观察】天翼云政务大模型“慧泽”:推动政务服务再升级,加速智慧城市再进化...

进入2023年以来&#xff0c;AIGC的爆发式增长推动了全球步入一个全新时代——大模型时代&#xff0c;它不仅引发了AI产业的整体升级换代&#xff0c;同时大模型与行业和应用场景的深度融合&#xff0c;更加速了AI的“走深向实”。 其中&#xff0c;政务业务不仅是连接政府、企业…

mstp vrrp bfd 实验

LSW1配置 <Huawei>sys Enter system view, return user view with CtrlZ. [Huawei]sys lsw1 [lsw1]vlan batch 10 20 30 [lsw1]int g0/0/1 [lsw1-GigabitEthernet0/0/1]port link-type access [lsw1-GigabitEthernet0/0/1]port default vlan 10 [lsw1-GigabitEthernet0…

Docker---cgroups资源限制

目录 一、cpu资源控制 1、 设置cpu使用率上限 2、设置cpu资源占用比&#xff08;设置多个容器时才有效&#xff09; 3、设置容器绑定指定的CPU 三、内存资源控制 四、磁盘IO配额控制 1、限制Block IO 2、限制bps和iops进行限制 一、cpu资源控制 cgroups是一个非常强大的…

用合成数据训练车辆姿态估计神经网络

我们的客户希望开发一款应用程序&#xff0c;引导用户通过 AR 指南和自动照片拍摄来拍摄更高质量的汽车照片。 本文重点介绍构建汽车姿态估计组件的技术。 在应用程序中&#xff0c;用户被引导站在与汽车一定的角度和距离&#xff0c;以标准化的方式捕捉最好的照片。 当用户处于…

LLMs Python解释器程序辅助语言模型(PAL)Program-aided language models (PAL)

正如您在本课程早期看到的&#xff0c;LLM执行算术和其他数学运算的能力是有限的。虽然您可以尝试使用链式思维提示来克服这一问题&#xff0c;但它只能帮助您走得更远。即使模型正确地通过了问题的推理&#xff0c;对于较大的数字或复杂的运算&#xff0c;它仍可能在个别数学操…

SketchyCOCO数据集进行前景图像、背景图像和全景图像的分类

SketchyCOCO数据集进行前景图像、背景图像和全景图像的分类 import os import shutildef CopyFile(src, dst, filename):if not os.path.exists(dst):os.makedirs(dst)print(create dir: dst)try:shutil.copy(src\\filename, dst\\filename)except Exception as e:print(cop…

Windows下Tensorflow docker python开发环境搭建

前置条件 windows10 更新到较新的版本&#xff0c;硬件支持Hyper-V。 参考&#xff1a;https://learn.microsoft.com/zh-cn/windows/wsl/install 启用WSL 在Powershell中输入如下指令&#xff1a; dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsys…