C++11(四)---可变参数模板

文章目录

    • 可变参数模板

可变参数模板

  • 参数包代表多个类型和参数

    // Args是一个模板参数包,args是一个函数形参参数包
    // 声明一个参数包Args...args,这个参数包中可以包含0到任意个模板参数。
    template <class ...Args>
    void ShowList(Args... args)
    {}
    //使用
    int main()
    {ShowList(1);ShowList(1,2,3.613);ShowList("1111",3,2,'c',vector<int>({111}));//...
    }
    
    • 查看参数包的参数个数

      • 使用sizeof,sizeof关键字也是在编译时就就行处理的
        template <class ...Args>
        void ShowList(Args... args)
        {cout << sizeof...(args) << endl;
        }
        //使用
        int main()
        {ShowList(1);ShowList(1,2,3.613);ShowList("1111",3,2,'c',vector<int>({111}));//...
        }
        
    • 打印参数包内容

      • 编译时递归推导
        因为是编译时递归推导,因此不能走运行时逻辑。

        //下面注释的这个是不行的,因为if语句里的逻辑是运行时的逻辑和处理,而这里的是编译时递归推导,是编译时进行的
        //template <class T, class ...Args>
        //void Print(T&& x, Args&&... args)
        //{
        //	cout << x << " ";
        //	Print(args...);
        //	if(sizeof...(args...) == 0)
        //		return;
        //}//当没参数的时候就调用该函数了
        void Print()
        {cout << endl;
        }// x存储传入Print参数包的第一个参数
        template <class T, class ...Args>
        void Print(T&& x, Args&&... args)
        {cout << x << " ";Print(args...);
        }// 编译时递归推导解析参数
        template <class ...Args>
        void ShowList(Args&&... args)
        {Print(args...);
        }
        

        这里和寻常递归不一样,这里是编译时递归推导

        • 演示编译时递归推导生成的函数

          // 编译器推导的
          void Print(int x, const char* y, double z)
          {cout << x << " ";Print(y, z);
          }void Print(const char* x, double z)
          {cout << x << " ";Print(z);
          }void Print(double x)
          {cout << x << " ";Print();
          }
          //如果不显示写Print();,那么编译时推导的Print();如下。很明显函数内没有x,会导致编译时报错。 如果最开始的函数模板内没有 cout << x << " ";语句。那么会接着推导出第二个Print();从而导致 有两个Print();函数,导致编译报错。
          void Print()
          {cout << x << " ";Print();
          }// 编译时递归推导解析参数
          template <class ...Args>
          void ShowList(Args&&... args)
          {Print(args...);
          }
          // 编译器实例化生成
          void ShowList(int x, const char* y, double z)
          {Print(x, y, z);
          }int main()
          {ShowList(1, "xxxxx", 2.2);return 0;
          }
          

          可见每次走的函数都是不同的函数。而运行时推导是对同一个函数进行多次调用,传入不同数据

      • 展开函数
        语法: 函数名(形参名)…

        
        template <class T>
        int PrintArg(T t)
        {cout << t << " ";return 0;
        }template <class ...Args>
        void ShowList(Args... args)
        {int arr[] = { PrintArg(args)... };cout << endl;
        }// 编译推演生成下面的函数
        void ShowList(int x, char y, std::string z)
        {int arr[] = { PrintArg(x),PrintArg(y),PrintArg(z) };cout << endl;
        }
        
    • 可变参数模板中使用完美转发样例

      template <class... Args>
      void emplace_back(Args&&... args)
      {insert(end(), std::forward<Args>(args)...);
      }
      
  • 介绍emplace_back接口

    emplace_back的功能和push_back一样。这里的参数包不是说能一下子push进去好几个数据,而是说当存储的数据为一个需要构造的时候,通过不断向下传这个参数包,使得可以直接构造出要push的数据,效率更高。
    在这里插入图片描述

    • 样例
      // emplace_back总体而言是更高效,推荐使用
      int main()
      {bit::list<bit::string> lt;// 左值bit::string s1("111111111111");lt.emplace_back(s1);// 右值lt.emplace_back(move(s1));// 直接把构造string参数包往下传,直接用string参数包构造string。是在emplace_back中new参数包,通过参数包下传,直接构造出了string参数。lt.emplace_back("111111111111");//如果是push_back("111111111111");的话,是先构造string,然后push_back中又new了一个string对象lt.emplace_back(10, 'x');cout << endl << endl;bit::list<pair<bit::string, int>> lt1;// 构造pair + 拷贝/移动构造pair到list的节点中data上pair<bit::string, int> kv("苹果", 1);lt1.emplace_back(kv);lt1.emplace_back(move(kv));cout << endl << endl;// 直接把构造pair参数包往下传,直接用pair参数包构造pairlt1.emplace_back("苹果", 1);return 0;
      }
      

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【qt】控件1

1.控件使能&#xff08;enabled&#xff09; QPushbutton*stnew QPushbutton(this);//定义一个按钮 st->setEnabled(false);//按钮设置不能使用当设置该控件不能使用的话&#xff0c;对应控件的子控件也不能使用 通过isEnabled()函数可以查看对应控件状态 演示&#xff1…

昇思MindSpore第二课---Transformer

1. Transformer的概念 Transformer是一种基于注意力机制结构的神经网络&#xff0c;其主要的作用就是用于处理机器翻译、语言建模以及文本生成等自然语言的处理。 比如人类在做一篇阅读理解的时候&#xff0c;我们的注意力可能主要集中在我们所阅读的这一行内容。而机器也是如此…

【Go】-bufio库解读

目录 Reader和Writer接口 bufio.Reader/Writer 小结 其他函数-Peek、fill Reader小结 Writer Scanner结构体 缓冲区对于网络数据读写的重要性 Reader和Writer接口 在net/http包生成的Conn 接口的实例中有两个方法叫做Read和Write接口 type Conn interface {Read(b []b…

mac 0S中虚拟机分辨率高怎么办

在VMware Fusion安装的Windows虚拟机有时候会遇到下图的问题&#xff0c;分辨率很高、桌面和任务栏的图标都很小&#xff0c;没办法正常使用。 解决方法&#xff1a; 点击工具栏中的扳手图标&#xff0c;打开设置。 打开系统设置中的“显示器”。 取消勾选“使用Retina全分辨率…

找不到d3dx9_43.dll怎么解决,d3dx9_43.dll缺失的七种解决方法

​在计算机游戏领域&#xff0c;遇到“找不到d3dx9_43.dll”错误信息是一个相当普遍的现象。这一问题不仅影响玩家的游戏体验&#xff0c;还可能导致游戏无法启动或运行不稳定。本文旨在深入解析这一问题的原因&#xff0c;并提供有效的解决方法&#xff0c;帮助广大游戏玩家轻…

论文《基于现实迷宫地形的电脑鼠设计》深度分析(四)——现实迷宫算法

论文概述 《基于现实迷宫地形的电脑鼠设计 》是由吴润强、庹忠曜、刘文杰、项璟晨、孙科学等人于2023年发表的一篇优秀期刊论文。其针对现阶段电脑鼠计算量庞大且不适用于现实迷宫地形的问题&#xff0c;特基于超声波测距与传统迷宫算法原理&#xff0c;设计出一款可在现实…

ARM(安谋) China处理器

0 Preface/Foreword 0.1 参考博客 Cortex-M23/M33与STAR-MC1星辰处理器 ARM China&#xff0c;2018年4月established&#xff0c;独立运行。 1 处理器类型 1.1 周易AIPU 1.2 STAR-MC1&#xff08;星辰处理器&#xff09; STAT-MC1&#xff0c;主要为满足AIOT应用性能、功…

Iview DatePicker 仅允许选择当前月份及以后的月份

iview DatePicker之前月份禁用且下月可用 html代码 <DatePicker type"month" :options"options4" :value"dialogForm.estimatedStartTimeWithCreate" on-change"monthTime($event, loadDateStart)" placeholder"请选择时间&q…

Redis 内存管理

参考&#xff1a;面试官&#xff1a;为什么 Redis 不立刻删除已经过期的数据&#xff1f; 目录 1.Redis 给缓存数据设置过期时间有什么用&#xff1f; 2.Redis 是如何判断数据是否过期的呢&#xff1f; 3.Redis 过期 key 删除策略了解么&#xff1f; 4.大量 key 集中过期怎…

【IC每日一题:SVA简介】

IC每日一题&#xff1a;SVA简介 1 断言概念1.1 断言优势&#xff1b;1.2 断言类型1.2.1 立即断言1.2.2 并行断言1.2.3 并发断言Demo 2 SVA语法2.1 蕴含操作符&#xff1a;|-> 和 ->2.1.1 蕴含操作符 |>2.1.2 蕴含操作符|-> 2.2 延时操作符2.2.1 ##n 操作符 2.3 重复…

深度学习之One Stage目标检测算法2

我们将对单次目标检测器&#xff08;包括SSD系列和YOLO系列等算法&#xff09;进行综述。我们将分析FPN以理解多尺度特征图如何提高准确率&#xff0c;特别是小目标的检测&#xff0c;其在单次检测器中的检测效果通常很差。然后我们将分析Focal loss和RetinaNet&#xff0c;看看…

【MySQL】优化方向+表连接

目录 数据库表连接 表的关系与外键 数据库设计 规范化 反规范化 事务一致性 表优化 索引优化 表结构优化 查询优化 数据库表连接 表的关系与外键 表之间的关系 常见表关系总结 一对一关系&#xff1a;每一条记录在表A中对应表B的唯一一条记录&#xff0c;反之也是&a…

SHELL笔记(概念+变量)

shell 概念 Shell 是一个命令行解释器&#xff0c;它充当用户与操作系统内核之间的桥梁。用户在 Shell 环境下输入各种命令&#xff0c;Shell 负责接收并分析这些命令&#xff0c;然后将其转换为内核能够理解和执行的系统调用。通过这种方式&#xff0c;用户可以便捷地操作计算…

统信UOS开发环境支持Golang

UOS为Golang开发者提供了各种编辑器和工具链的支持,助力开发者实现高质量应用的开发。 文章目录 一、环境部署Golang开发环境安装二、代码示例Golang开发案例三、常见问题1. 包导入错误2. 系统资源限制一、环境部署 Golang开发环境安装 golang开发环境安装步骤如下: 1)安装…

web前端开发--盒子属性

1、设置背景图像固定 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>设置背景图像固定</title><style type"text/css">/*p{background-attachment: scroll;/*fixed固定*//*随元素滚动还是固定*/}&…

Python数据分析NumPy和pandas(三十五、时间序列数据基础)

时间序列数据是许多不同领域的结构化数据的重要形式&#xff0c;例如金融、经济、生态学、神经科学和物理学。在许多时间点重复记录的任何内容都会形成一个时间序列。许多时间序列是固定频率的&#xff0c;也就是说&#xff0c;数据点根据某些规则定期出现&#xff0c;例如每 1…

前端开发之打印功的使用和实例(vue-print-nb)

通过插件来进行实现 前言效果图1、安装插件vue2vue32、 引入Vue项目2、 使用2.1、在项目中创建按钮并且使用v-print绑定绑定打印事件2.2、编写要打印的内容,给内容附加唯一的id2.3、绑定的时间的方法和参数3、整体代码(此代码是通过vue3来进行实现的但是逻辑都是一样的)前言…

使用Web Animations API实现复杂的网页动画效果

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 使用Web Animations API实现复杂的网页动画效果 使用Web Animations API实现复杂的网页动画效果 使用Web Animations API实现复杂…

分享一个mysql-sql优化经验 in (xxx)的优化【 in(集合)改成not in(反集合) 】

一、优化前 如下sql&#xff0c;直接执行时间需要18.341秒 二、优化后 将 in(集合) 改成 not in(反集合)&#xff0c;如下图&#xff0c;执行性能提升至少4倍&#xff0c;需要4.643秒&#xff0c;并且查询结果不变 三、原因分析 为什么速度会变快那么多&#xff1f; in (集…

传感器页面、屏幕刷新任务学习

一、user_SensorPageTask 传感器页任务 ​ /* Private includes -----------------------------------------------------------*/ //includes #include "user_TasksInit.h" #include "user_ScrRenewTask.h" #include "user_SensorPageTask.h" …