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.rhkb.cn/news/473342.html

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

相关文章

基于Springboot+Vue的中国蛇类识别系统 (含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 这个系…

大数据新视界 -- 大数据大厂之 Impala 性能飞跃:分区修剪优化的应用案例(下)(22 / 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

ES6标准-Promise对象

目录 Promise对象的含义 Promise对象的特点 Promise对象的缺点 Promise对象的基本用法 Promise对象的简单例子 Promise新建后就会立即执行 Promise对象回调函数的参数 Promise参数不会中断运行 Promise对象的then方法 Promise对象的catch()方法 Promise状态为resolv…

【目标检测】【Ultralytics-YOLO系列】Windows11下YOLOV5人脸目标检测

【目标检测】【Ultralytics-YOLO系列】Windows11下YOLOV5人脸目标检测 文章目录 【目标检测】【Ultralytics-YOLO系列】Windows11下YOLOV5人脸目标检测前言YOLOV5模型运行环境搭建YOLOV5模型运行数据集准备YOLOV5运行模型训练模型验证模型推理 总结 前言 Ultralytics YOLO 是一…

使用Axios函数库进行网络请求的使用指南

目录 前言1. 什么是Axios2. Axios的引入方式2.1 通过CDN直接引入2.2 在模块化项目中引入 3. 使用Axios发送请求3.1 GET请求3.2 POST请求 4. Axios请求方式别名5. 使用Axios创建实例5.1 创建Axios实例5.2 使用实例发送请求 6. 使用async/await简化异步请求6.1 获取所有文章数据6…

windows工具 -- 使用rustdesk和云服务器自建远程桌面服务, 手机, PC, Mac, Linux远程桌面 (简洁明了)

目的 向日葵最先放弃了, todesk某些功能需要收费, 不想用了想要 自己搭建远程桌面 自己使用希望可以电脑 控制手机分辨率高一些 原理理解 ubuntu云服务器配置 够买好自己的云服务器, 安装 Ubuntu操作系统 点击下载 hbbr 和 hbbs 两个 deb文件: https://github.com/rustdesk/…

MySQL-关联查询和子查询

目录 一、笛卡尔积 二、表连接 1、内部连接 1.1 等值连接 1.2 非等值连接 2、外部链接 2.1 左外连接-LEFT JOIN 2.2 右外连接-RIGHT JOIN 2.3 全关联-FULL JOIN/UNION 三、子查询 1、嵌套子查询 2、相关子查询 3、insert和select语句添加数据 4、update和select语…

AWTK-WIDGET-WEB-VIEW 实现笔记 (1) - 难点

webview 提供了一个跨平台的 webview 库&#xff0c;其接口简单&#xff0c;提供的例子也直观易懂。但是把它集成到 AWTK 里&#xff0c;还是遇到一些难题&#xff0c;这里记录一下&#xff0c;供有需要的朋友参考。 1. 作为 AWTK 控件 webview 提供的例子都是独立的程序&…

类与对象;

目录 一、认识类&#xff1b; 1、类的引入&#xff1b; 2、类的定义&#xff1b; 类的两种定义方式&#xff1a; 3、类的访问限定符及封装&#xff1b; 4、类的作用域&#xff1b; 5、类的实例化&#xff1b; 6、类对象模型&#xff1b; 计算类对象的大小&#xff1b; …

Ubuntu22.04LTS 部署前后端分离项目

一、安装mysql8.0 1. 安装mysql8.0 # 更新安装包管理工具 sudo apt-get update # 安装 mysql数据库&#xff0c;过程中的选项选择 y sudo apt-get install mysql-server # 启动mysql命令如下 &#xff08;停止mysql的命令为&#xff1a;sudo service mysql stop&#xff0…

使用 Ant Design Vue 自定渲染函数customRender实现单元格合并功能rowSpan

使用 Ant Design Vue 自定渲染函数customRender实现单元格合并功能rowSpan 背景 在使用Ant Design Vue 开发数据表格时&#xff0c;我们常常会遇到需要合并单元格的需求。 比如&#xff0c;某些字段的值可能会在多行中重复出现&#xff0c;而我们希望将这些重复的单元格合并为…

27.<Spring博客系统③(实现用户退出登录接口+发布博客+删除/编辑博客)>

PS&#xff1a;关于打印日志 1.建议在关键节点打印日志。 ①请求入口。 ②结果响应 2.在可能发生错误的节点打印日志 3.日志不是越多越好。因为打日志也会消耗性能。 日志也可以配置去除重复日志。 一、用户退出功能 判断用户退出。我们只需要在前端将token删掉就可以了。 由于…

[前端面试]javascript

js数据类型 简单数据类型 null undefined string number boolean bigint 任意精度的大整数 symbol 创建唯一且不变的值&#xff0c;常用来表示对象属性的唯一标识 复杂数据类型 object&#xff0c;数组&#xff0c;函数,正则,日期等 区别 存储区别 简单数据类型因为其大小固定…

uniapp自动注册机制:easycom

传统 Vue 项目中&#xff0c;我们需要注册、导入组件之后才能使用组件。 uniapp 框架提供了一种组件自动注册机制&#xff0c;只要你在 components 文件夹下新建的组件满足 /components/组件名/组件名.vue 的命名规范&#xff0c;就能直接使用。 注意&#xff1a;组件的文件夹…

人工智能与SEO优化中的关键词策略解析

内容概要 在当今数字化快速发展的时代&#xff0c;人工智能&#xff08;AI&#xff09;与搜索引擎优化&#xff08;SEO&#xff09;的结合正变得愈发重要。关键词策略是SEO优化的一项基础工作&#xff0c;它直接影响到网站的可见性和流量。通过运用智能算法&#xff0c;企业能…

【异常解决】Linux shell报错:-bash: [: ==: 期待一元表达式 解决方法

博主介绍&#xff1a;✌全网粉丝21W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…

卷径计算(基于卷径变化微分方程计算实时卷径)

这里本质是积分法计算实时卷径,PLC里如何实现数值积分器算法请参考下面文章链接: 博途PLC数值积分器(矩形积分和梯形积分法自由切换) 博途PLC数值积分器(矩形梯形积分自由切换)_博图 积分计算-CSDN博客文章浏览阅读505次。本文详细介绍了博途PLC的数值积分器功能,涵盖了矩…

【Mysql】Mysql的多表查询---多表联合查询(上)

1、介绍 多表查询就是同时查询两个或者两个以上的表&#xff0c;因为有的时候&#xff0c;用户在查看数据的时候&#xff0c;需要显示的数据来自多张表&#xff0c;多表查询有以下分类&#xff1a; &#xff08;1&#xff09;交叉连接查询&#xff08;产生笛卡尔积&#xff0…

Shell基础(4)

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团…

跨平台WPF框架Avalonia教程 十五

ListBox 列表框 列表框从元素源集合中显示多行元素&#xff0c;并允许选择单个或多个。 列表中的元素可以组合、绑定和模板化。 列表的高度会扩展以适应所有元素&#xff0c;除非特别设置&#xff08;使用高度属性&#xff09;&#xff0c;或由容器控件设置&#xff0c;例如…