c++右值引用及使用

2024-08-25 00:08
文章标签 c++ 使用 引用 右值

本文主要是介绍c++右值引用及使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、几个基本概念

1.1右值

右值表示无法获取地址的对象,有常量值、函数返回值、lambda表达式等。无法获取地址,但不表示其不可改变,当定义了右值的右值引用时就可以更改右值。

1.2 右值引用

c++11中增加了右值引用,右值引用关联到右值时,右值被存储到特定位置,右值引用指向该特定位置,也就是说,右值虽然无法获取地址,但是右值引用是可以获取地址的,该地址表示临时对象的存储位置。语法如下:

int && iii = 10;

1.3 左值引用和右值引用的相互赋值

能将右值引用赋值给左值引用,该左值引用绑定到右值引用指向的对象,在早期的c++中,引用没有左右之分,引入了右值引用之后才被称为左值引用,所以说左值引用其实可以绑定任何对象。这样也就能理解为什么const左值引用能赋予常量值。

int&& iii = 10;
int& ii = iii;      //ii等于10,对ii的改变同样会作用到iii

 

二、右值引用和移动语义

在旧的c++中,出现了很多的不必须要的拷贝,因为在某些情况下,对象拷贝完之后就下来就销毁了。新标准引入了移动操作,减少了很多的复制操作,而右值引用正式为了支持移动操作而引入的新的引用类型。

 

2.1 标准库move函数

根据右值引用的语法规则,不能将右值引用绑定到一个左值上

c++11引入右值引用,并且提供了move函数,用来获得绑定到左值上的右值引用,此函数定义在头文件utility中。

Int &&iii = move(ii)

调用move之后,必须保证除了对ii复制或销毁它外,我们将不再使用它,在调用move之后,我们不能对移动源后对象做任何假设。

 

2.2 模板实参推断和引用

为了理解move函数的实现,首先需要理解模板实参推断和引用。

当左值引用作为参数时,看几个例子:

template<class T> void f1(T&) {}
f1(i)           //i是一个int,模板参数类型T是int
f1(ci)         //ci是一个const int,模板参数T是const int
fl(5)           //错误:传递给一个&参数的实参必须是一个左值

如果函数的参数是const的引用时:

template<class T> void f2(const T&) {}
f2(i)           //i是一个int,模板参数类型T是int,因为非const可以转化为const
f2(ci)         //ci是一个const int,模板参数T是int
f2(5)          //看前面,const的引用可以绑定右值,T是int

当参数是右值引用时,

template<class T> void f3(T&&) {}
f3(5)          // T是int

 

2.3 引用折叠和右值引用参数

按照道理来说,f3(i)是应该不正确的,因为无法将右值引用绑定到一个左值上,但是,c++中有两个正常绑定规则的例外,允许这种绑定。这两个例外规则是move正确工作的基础

例外1右值引用的类型推断。当我们将一个左值传递给函数的右值引用作为参数时(函数参数为T&&),编译器推断模板类型参数为实参的左值引用类型,,因此,调用f3(i)时,T被推断为int&,而不是int。并且,模板函数中对参数的改变会反映到调用时传入的实参。

通常,我们不能直接定义一个引用的引用,但是同过类型别名(使用typedef)和模板间接定义是可以的。

例外2引用折叠。当定义了引用的引用时,则这些引用形成了“折叠”,所有的情况下(除了一个例外),引用会折叠成一个普通的左值引用类型。这个例外就是右值引用的右值引用:

l  X&  &&、X&  &&、X&&  &都折叠成X&

l  类型X&&  &&折叠成X&&

//左值和const右值

这篇关于c++右值引用及使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1103999

相关文章

Java使用Curator进行ZooKeeper操作的详细教程

《Java使用Curator进行ZooKeeper操作的详细教程》ApacheCurator是一个基于ZooKeeper的Java客户端库,它极大地简化了使用ZooKeeper的开发工作,在分布式系统... 目录1、简述2、核心功能2.1 CuratorFramework2.2 Recipes3、示例实践3

springboot security使用jwt认证方式

《springbootsecurity使用jwt认证方式》:本文主要介绍springbootsecurity使用jwt认证方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录前言代码示例依赖定义mapper定义用户信息的实体beansecurity相关的类提供登录接口测试提供一

go中空接口的具体使用

《go中空接口的具体使用》空接口是一种特殊的接口类型,它不包含任何方法,本文主要介绍了go中空接口的具体使用,具有一定的参考价值,感兴趣的可以了解一下... 目录接口-空接口1. 什么是空接口?2. 如何使用空接口?第一,第二,第三,3. 空接口几个要注意的坑坑1:坑2:坑3:接口-空接口1. 什么是空接

springboot security快速使用示例详解

《springbootsecurity快速使用示例详解》:本文主要介绍springbootsecurity快速使用示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录创www.chinasem.cn建spring boot项目生成脚手架配置依赖接口示例代码项目结构启用s

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

java中使用POI生成Excel并导出过程

《java中使用POI生成Excel并导出过程》:本文主要介绍java中使用POI生成Excel并导出过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求说明及实现方式需求完成通用代码版本1版本2结果展示type参数为atype参数为b总结注:本文章中代码均为

Spring Boot3虚拟线程的使用步骤详解

《SpringBoot3虚拟线程的使用步骤详解》虚拟线程是Java19中引入的一个新特性,旨在通过简化线程管理来提升应用程序的并发性能,:本文主要介绍SpringBoot3虚拟线程的使用步骤,... 目录问题根源分析解决方案验证验证实验实验1:未启用keep-alive实验2:启用keep-alive扩展建

使用Java实现通用树形结构构建工具类

《使用Java实现通用树形结构构建工具类》这篇文章主要为大家详细介绍了如何使用Java实现通用树形结构构建工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录完整代码一、设计思想与核心功能二、核心实现原理1. 数据结构准备阶段2. 循环依赖检测算法3. 树形结构构建4. 搜索子

GORM中Model和Table的区别及使用

《GORM中Model和Table的区别及使用》Model和Table是两种与数据库表交互的核心方法,但它们的用途和行为存在著差异,本文主要介绍了GORM中Model和Table的区别及使用,具有一... 目录1. Model 的作用与特点1.1 核心用途1.2 行为特点1.3 示例China编程代码2. Tab

SpringBoot使用OkHttp完成高效网络请求详解

《SpringBoot使用OkHttp完成高效网络请求详解》OkHttp是一个高效的HTTP客户端,支持同步和异步请求,且具备自动处理cookie、缓存和连接池等高级功能,下面我们来看看SpringB... 目录一、OkHttp 简介二、在 Spring Boot 中集成 OkHttp三、封装 OkHttp