左值右值引用,完美转发

1.c++98/03,类模板和函数模板只能含固定数量的模板参数,c++11的新特性可以创建接受可变参数的函数模板和类模板

//Args是一个模板参数包,args是一个函数形参参数包
//声明一个参数包Args… args,这个参数包可以包括0到任意个模板参数
template<class …Args>
void showlist(Args… args)
由于args前面有省略号,它就是一个可变模板参数,把带有省略号的参数称为参数包,它里面包含着0到N个模板参数,我们是无法直接获取参数包args,只能通过展开参数包的方式获取参数包的每个参数,语法不支持args[i]的方式获取可变参数
获取参数包的方式
1.递归函数方式展开函数包

//编译的递归推演
//第一个模板参数依次解析获取参数值
void _showlist() {
	cout << "没有模板参数" << endl;
}
template<class T>
void _showlist(const T& val) {
	cout << val << "只有一个模板参数" << " ";
}
template<class T, class ...Args>
void _showlist(const T& val, Args...args) {
	cout << val << endl;
	_showlist(args...);
}
template<class ...Args>
void showlist(Args...args) {
	_showlist(args...);
}
int main() {
	showlist();
	showlist(1);
	showlist(1, 2, 3);
	showlist(1, "ss", 2.2);
}

在这里插入图片描述
例如我们showlist(“Hello”,666,‘A’,3.1415926);
其中的模板参数包包含类型参数[const char*, int, char, double],函数参数包包含值参数[“Hello”, 666, ‘A’, 3.1415926]
在调用可变参数版本时:
“Hello"被传给形参T,剩余的参数: 666, ‘A’, 3.1415926。 然后,类型参数: int, char, double将被放入模板参数包Args中。值参数: 666, ‘A’, 3.1415926将被放入函数参数包args中。打印value的值"Hello”,开始下一轮递归。666被传给形参T,剩余的参数: ‘A’, 3.1415926。 然后,类型参数: char, double将被放入模板参数包Args中。值参数: ‘A’, 3.1415926将被放入函数参数包args中。打印T的值666,开始下一轮递归’A’被传给形参T,剩余的参数:3.1415926。 然后,类型参数: double将被放入模板参数包Args中。值参数: 3.1415926将被放入函数参数包args中。打印value的值’A’,开始下一轮递归。此时,参数包中只有一个参数,所以将调用只有一个参数版本的Print(), 3.1415926被传给形参arg,打印arg的值3.1415926,结束递归。

要初始化arr,强行让解析参数包,参数包有几个参数,printArg就一次推演生成几个

template<class T>
int  print(T val) {
	cout << val << " ";
	return 0;
}
template<class ...Args>
void showlist(Args...args) {
	int arr[] = {print(args)...};
	cout << endl;
}
int main() {
	showlist(1, 2, "1233", 'a');
}

emplace_back

template<class... Args>
void emplace_back(Args&&.. args){
Node*newnode=new Node(args...);
}
template<class... Args>
list_node(Args...args)
:data(args...)//例如,list中为pair,用参数包直接调用pair的构造
,next(nullptr)
,prev(nullptr)
{}

//直接把参数包不断往下传,直接构造到节点中的val上

emplace_back在实现时,则是在容器尾部创建这个元素,省去了拷贝或移动元素的过程
push_back首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中
2.左值和右值
一般认为,可以放在=左边的,或者能够取地址的,称为左值,只能放在等号右边的,或者不能取地址的,称为右值
常见右值 `

 10//字面常量
 i+j//表达式返回值 
 fmin(i,j)//函数调用返回值`

c++11对右值进行了区分
①.纯右值 a+b,100
②.将亡值 表达式的中间结果,函数按照值的方式进行返回
左值引用常见场景
①.引用传参 void func(const T&x)
②.引用返回 T&func() 出了函数作用域,对象生命周期还未结束
移动语义的出现
移动语义:将一个对象中的资源移动到另一个对象中的方式

为了避免 构造临时对象,深拷贝进行拷贝构造,再构造的重复流程,使用移动构造,构造临时对象通过移动构造将资源转移到临时对象中,而临时对象本身又是右值(将亡值),构造的时候会将临时对象的资源转移到要构造的对象中

要注意,右值引用本身的属性是左值

   double&& r = 1.1 + 2.2;
   double& c = r;

完美转发

template<tyname T>
void PerfectForward(T&&t){
Func(forward<T>(t));
}

比如PerfectForward(10),我们想输出右值引用,但由于右值引用的属性是左值

perfectForward为转发的模板函数,Func为实际目标函数,完美转发是目标函数总希望将参数按照传递给转发函数的实际类型转给目标函数,而不产生额外的开销,就好像转发者不存在一样
所谓完美:函数模板在向其它函数传递形参的时候,如果相应实参是左值,它就应该被转发为左值,如果相应实参是右值,它就应该被转发为右值。

#include<bits/stdc++.h>
using namespace std;
void func(int&x){
	cout<<"左值引用"<<endl;
}
void func(int&&x){
	cout<<"右值引用"<<endl; 
}
void func(const int &x){
	cout<<"const 左值引用"<<endl; 
}
void func(const int&&x){
	cout<<"const 右值引用"<<endl;
}
template<typename T>
void perfectForward(T&&t){
	func(forward<T>(t));
}
int main(){
	int c;
	perfectForward(3);
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

成功案例分享:物业管理小程序如何助力打造智慧社区

随着科技的进步和互联网的普及&#xff0c;数字化转型已经渗透到各个行业&#xff0c;包括物业管理。借助小程序这一轻量级应用&#xff0c;物业管理可以实现线上线下服务的无缝对接&#xff0c;提升服务质量&#xff0c;优化用户体验。本文将详细介绍如何通过乔拓云网设计小程…

如何确保游戏翻译的质量

随着全球化的加速和游戏行业的国际化&#xff0c;越来越多的玩家开始接触并喜欢玩国际游戏。然而&#xff0c;由于语言障碍&#xff0c;很多玩家无法理解游戏中的文本和对话&#xff0c;这严重影响了游戏体验。因此&#xff0c;游戏翻译变得尤为重要。那么&#xff0c;如何确保…

【模式识别】探秘判别奥秘:Fisher线性判别算法的解密与实战

​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《模式之谜 | 数据奇迹解码》⏰诗赋清音&#xff1a;云生高巅梦远游&#xff0c; 星光点缀碧海愁。 山川深邃情难晤&#xff0c; 剑气凌云志自修。 目录 &#x1f30c;1 初识模式识…

助力智能人群检测计数,基于DETR(DEtectionTRansformer)开发构建通用场景下人群检测计数识别系统

在一些人流量比较大的场合&#xff0c;或者是一些特殊时刻、时段、节假日等特殊时期下&#xff0c;密切关注当前系统所承载的人流量是十分必要的&#xff0c;对于超出系统负荷容量的情况做到及时预警对于管理团队来说是保障人员安全的重要手段&#xff0c;本文的主要目的是想要…

读算法霸权笔记01_数学杀伤性武器

1. 数学应用助推数据经济&#xff0c;但这些应用的建立是基于不可靠的人类所做的选择 1.1. 房地产危机&#xff0c;大型金融机构倒闭&#xff0c;失业率上升&#xff0c;在幕后运用着神奇公式的数学家们成为这些灾难的帮凶 1.2. 数学逐渐不再关注全球金融市场动态&#xff0c…

Flutter笔记:Web支持原理与实践

Flutter笔记 Web支持原理与实践 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com CSDN&#xff1a;https://blog.csdn.net/qq_28550263/article/details/135037756 华为开发者社区…

任天堂,steam游戏机通过type-c给VR投屏与PD快速充电的方案 三type-c口投屏转接器

游戏手柄这个概念&#xff0c;最早要追溯到二十年前玩FC游戏的时候&#xff0c;那时候超级玛丽成为了许多人童年里难忘的回忆&#xff0c;虽然长大了才知道超级玛丽是翻译错误&#xff0c;应该是任天堂的超级马里奥&#xff0c;不过这并不影响大家对他的喜爱。 当时FC家用机手柄…

【Android】存储读取权限管理理解和api 调研报告

背景 工作和学习需要了解android 权限管理和 对应的api 调用逻辑。 学习 内部路径 不用权限 /data/data/应用包名 相关API Context 类 getCacheDir 缓存路径 getCodeCacheDir 示意路径 getFilesDir 内部文件 文件路径 fileList &#xff08;files 下的所有文件名&…

【Unity基础】9.地形系统Terrain

【Unity基础】9.地形系统Terrain 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity基础系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;一&#xff09;地形编辑器Terrain &#xff08;1&#xff09;创建地形 游戏场景中大多数的山川河流地表地貌都是基…

【单调栈】LeetCode:2818操作使得分最大

作者推荐 map|动态规划|单调栈|LeetCode975:奇偶跳 涉及知识点 单调栈 题目 给你一个长度为 n 的正整数数组 nums 和一个整数 k 。 一开始&#xff0c;你的分数为 1 。你可以进行以下操作至多 k 次&#xff0c;目标是使你的分数最大&#xff1a; 选择一个之前没有选过的 非…

Pipelined-ADC设计二——结构指标及非理想因素(Part1)

本章将详细介绍电路各个模块的设计思路和设计中需要注意的关键点&#xff0c;给出流水线ADC中的非理想因素&#xff0c;并计算出流水线ADC各个模块具体指标。根据电路中信号的传输方向&#xff0c;依次介绍采样保持电路、Sub_ADC&#xff0c;MDAC 等模块的设计。&#xff08;本…

CSS自适应分辨率 amfe-flexible 和 postcss-pxtorem:Webpack5 升级后相关插件和配置更新说明

前言 项目对应的 webpack5 版本如下&#xff1a; npm i webpack5.89.0 -D npm i webpack-cli5.1.4 -D升级插件 说明一下&#xff0c;我更喜欢固定版本号&#xff0c;这样随机bug会少很多&#xff0c;更可控~ npm i postcss-loader6.1.1 -D npm i postcss-pxtorem6.0.0 -D配…

Hive-high Avaliabl

hive—high Avaliable ​ hive的搭建方式有三种&#xff0c;分别是 ​ 1、Local/Embedded Metastore Database (Derby) ​ 2、Remote Metastore Database ​ 3、Remote Metastore Server ​ 一般情况下&#xff0c;我们在学习的时候直接使用hive –service metastore的方式…

基于SpringBoot简洁优雅的个人博客系统

源代码下载地址&#xff1a; 点击这里下载 项目备注 1、该资源内项目代码都经过测试运行成功&#xff0c;功能ok的情况下才上传的&#xff0c;请放心下载使用&#xff01; 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或…

arduino+pir传感器练习和lcd屏幕库练习

// C code // #include <Adafruit_LiquidCrystal.h>//lcd屏幕库 库根据屏幕下载Adafruit_LiquidCrystal lcd_1(0);//定义lcd屏幕对象void setup() {pinMode(5, INPUT);//定义pir针脚lcd_1.begin(16, 2);/* begin(16, 2)&#xff1a;是 lcd_1 对象的一个方法调用&#xff…

微软的word文档中内置背景音乐步骤(打开自动播放)

目录 一、前言 二、操作步骤 一、前言 有时候需要在word文档里面打开的时候就自动播放音乐或者音频&#xff0c;那么可以用微软的word来按照操作步骤去这样完成。 如果没有微软office的&#xff0c;可以下载这个是2021专业版的。因为office只能免费使用一段时间&#xff0c…

thinkphp+vue+mysql酒店客房管理系统 b1g8z

本系统包括前台界面、用户界面和管理员界面、员工界面。在前台界面里游客和用户可以浏览客房信息、公告信息等&#xff0c;用户可以预定客房&#xff0c;在用户中心界面里&#xff0c;用户可以管理预定信息&#xff0c;管理员负责用户预定的审核以及客房的发布、用户的入住等。…

Java之HashMap核心源码解读

HashMap核心源码解读 HashMap 简介 HashMap 主要用来存放键值对&#xff0c;它基于哈希表的 Map 接口实现&#xff0c;是常用的 Java 集合之一&#xff0c;是非线程安全的。 HashMap 可以存储 null 的 key 和 value&#xff0c;但 null 作为键只能有一个&#xff0c;null 作…

DshanMCU-R128s2启动与资源划分

启动与资源划分 下面简单介绍一下 R128 方案的资源划分与启动流程。 资源划分 CPU 资源划分 这只是默认配置方案&#xff0c;CPU 资源划分可以按照需求任意修改 CPU功能说明M33控制核。运行 WI-FI/BT 固件、协议栈、驱动、休眠唤醒、安全启动、安全控制C906应用核。运行大…

Linux内核模块文件组成介绍

Linux驱动开发主要的工作就是编写模块&#xff0c;一个典型的Linux内核模块文件.ko 主要由以下几个部分组成。 模块加载函数(必须) 当通过insmod或modprobe命令加载内核模块时&#xff0c;模块的加载函数会自动被内核执行&#xff0c;完成本模块的相关初始化工作。 Linux内核模…
最新文章