当前位置: 首页 > news >正文

C++模板元编程(一)——可变参数模板

这个系列主要记录C++模板元编程的常用语法


文章目录

  • 引言
  • 语法
  • 应用
    • 函数模板
      • 可变参数的打印
      • 可变参数的最小/最大函数
    • 类模板
  • 参考文献


引言

在C++11之前,函数模板和类模板只支持含有固定数量的模板参数。C++11增强了模板功能,允许模板定义中包含任意个(包括0个)模板参数,即可变参数模板。


语法

template<typename... Types>

其中 ... 可接纳的模板参数>=0
如果不希望产生模板参数个数为0的变长参数模板,则可以采用以下定义:

template<typename Head, typename... Tail>

由于多了Head类型,该模板必须有一个及以上的模板参数。


应用

函数模板

可变参数的打印

函数模板中一种常见的使用可变参数模板的场景是以递归的方式取出可用参数:

#include <iostream>void print() {}template<typename T, typename... Types>
void print(const T& firstArg, const Types&... args) {std::cout << firstArg << " " << sizeof...(args) << std::endl;print(args...);
}template <typename... Types>
void print(const Types&... args) {std::cout << "print(...)" << std::endl;
}int main(int argc, char* argv[]) {print(3.0f, "hello world", 10);return 0;
}

上面例子表示我们想要输出一个单精度浮点值+字符串+整型值:

  • 上面的 void print() {} 代表模板递归的终止。
  • print(args...) 展开参数,向下模板递归。
  • sizeof...(args) 得到参数的个数。

最终输出为

考虑如下情况,如果除了有上面的模板,我们还定义了一个完全泛化的模板:

template <typename... Types>
void print(const Types&... args) {std::cout << "print(...)" << std::endl;
}

那么输出结果是怎么样的?
答案是还是输出上面的值,这是因为编译器对于偏泛化和偏特化都满足的情况,会选择偏特化的模板。


可变参数的最小/最大函数

有时我们想得到可变参数的最小/最大函数,可以如下实现:

#include <iostream>template <typename T>
T m_min(T value) {return value;
}template <typename T, typename... Types>
T m_min(T value, Types... args) {return std::min(value, m_min(args...));
}int main(int argc, char *argv[]) {std::cout << my_min(4, 3, 1, 2) << std::endl;return 0;
}

类模板

可变参数模板也可以用于类模板中,比如STL中的tuple

#include <iostream>template<typename... Values> class tuple;
template<> class tuple<> {};template<typename Head, typename... Tail>
class tuple<Head, Tail...>: private tuple<Tail...>
{typedef tuple<Tail...> inherited;
public:tuple() {}tuple(Head v, Tail... vtail) : m_head(v), inherited(vtail...) {}Head& head() { return m_head; }inherited& tail() { return *this; }
protected:Head m_head;
};int main(int argc, char* argv[]) {tuple<float, std::string, int> t(3.0f, "hello world", 10);std::cout << t.head() << " " << t.tail().head() << " " << t.tail().tail().head() << std::endl;return 0;
}

通过可变参数模板,实现递归继承,根基类为 template<> class<>{},父类成员在内存中位于子类成员之前。

这里的输出为


参考文献

【C++】C++11可变参数模板(函数模板、类模板)

相关文章:

C++模板元编程(一)——可变参数模板

这个系列主要记录C模板元编程的常用语法 文章目录 引言语法应用函数模板可变参数的打印可变参数的最小/最大函数 类模板 参考文献 引言 在C11之前&#xff0c;函数模板和类模板只支持含有固定数量的模板参数。C11增强了模板功能&#xff0c;允许模板定义中包含任意个(包括0个)…...

kafka中

Kafka RocketMQ概述 RabbitMQ概述 ActiveMQ概述 ZeroMQ概述 MQ对比选型 适用场景-从公司基础建设力量角度出发 适用场景-从业务场景出发 Kafka配置介绍 运行Kafka 安装ELAK 配置EFAK EFAK界面 KAFKA常用术语 Kafka常用指令 Kafka中消息读取 单播消息 group.id 相同 多播消息 g…...

Android 获取当前电池状态

在 API 级别 23 上获取充电状态 要在 API 级别 23 上获取电池的当前状态&#xff0c;只需使用电池管理器系统服务&#xff1a; BatteryManager batteryManager (BatteryManager) getSystemService(BATTERY_SERVICE); boolean isCharging batteryManager.isCharging();使用 S…...

【JVM 的内存模型】

1. JVM内存模型 下图为JVM内存结构模型&#xff1a; 两种执行方式&#xff1a; 解释执行&#xff1a;JVM是由C语言编写的&#xff0c;其中有C解释器&#xff0c;负责先将Java语言解释翻译为C语言。缺点是经过一次JVM翻译&#xff0c;速度慢一点。JIT执行&#xff1a;JIT编译器…...

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【17】认证服务01—短信/邮件/异常/MD5

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【17】认证服务01 环境搭建验证码倒计时短信服务邮件服务验证码短信形式&#xff1a;邮件形式&#xff1a; 异常机制MD5参考 环境搭建 C:\Windows\System32\drivers\etc\hosts 192.168.…...

geom buffer制作

1. auto buffer_geom line_string->buffer(15);//buffer //这个是x和y各扩大段15个单位 auto buffer_geom line_string->buffer(15);//buffer //这个是x和y各扩大段15米 获取buffer坐标 auto boundary buffer_geom->getBoundary(); auto boundary_coords boun…...

微软正在放弃React

最近&#xff0c;微软Edge团队撰写了一篇文章&#xff0c;介绍了微软团队如何努力提升Edge浏览器的性能。但在文中&#xff0c;微软对React提出了批评&#xff0c;并宣布他们将不再在Edge浏览器的开发中使用React。 我将详细解析他们的整篇文章内容&#xff0c;探讨这一决定对…...

U盘非安全退出后的格式化危机与高效恢复策略

在数字化时代&#xff0c;U盘作为数据存储与传输的重要工具&#xff0c;其数据安全备受关注。然而&#xff0c;一个常见的操作失误——U盘没有安全退出便直接拔出&#xff0c;随后再插入时却遭遇“需要格式化”的提示&#xff0c;这不仅让用户措手不及&#xff0c;更可能意味着…...

安卓虚拟位置修改

随着安卓系统的不断更新&#xff0c;确保软件和应用与最新系统版本的兼容性变得日益重要。本文档旨在指导用户如何在安卓14/15系统上使用特定的功能。 2. 系统兼容性更新 2.1 支持安卓14/15&#xff1a;更新了对安卓14/15版本的支持&#xff0c;确保了软件的兼容性。 2.2 路…...

大数据面试题之Presto[Trino](5)

目录 Presto的扩展性如何&#xff1f; Presto如何与Hadoop生态系统集成&#xff1f; Presto是否可以连接到NoSQL数据库&#xff1f; 如何使用Presto查询Kafka中的数据&#xff1f; Presto与Spark SQL相比有何优势和劣势&#xff1f; Presto如何与云服务集成&#xff1…...

对编程开发人员在今年的一些建议

一、今年的大环境 这几天身体不太好&#xff0c;又不断看到地狱级的就业问题。所以有些想法想和大家分享一下&#xff0c;并提出自己的一些想法和建议。今年的大环境不好&#xff0c;做为非专业人士&#xff0c;咱们也不分析&#xff0c;以免贻笑大方。但针对大环境下的计算机…...

VSCode设置好看清晰的字体!中文用鸿蒙,英文用Jetbrains Mono

一、中文字体——HarmonyOS Sans SC 1、下载字体 官网地址&#xff1a;https://developer.huawei.com/consumer/cn/design/resource/ 直接下载&#xff1a;https://communityfile-drcn.op.dbankcloud.cn/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20230517…...

SpringBoot新手快速入门系列教程四:创建第一个SringBoot的API

首先我们用IDEA新建一个项目&#xff0c;请将这些关键位置按照我的设置设置一下 接下来我将要带着你一步一步创建一个Get请求和Post请求&#xff0c;通过客户端请求的参数&#xff0c;以json格式返回该参数{“message”:"Hello"} 1,先在IDE左上角把这里改为文件模式…...

第1集《修习止观坐禅法要》

《修习止观坐禅法要》诸位法师&#xff0c;诸位学员&#xff0c;阿弥院佛&#xff01; 我们今天能够暂时放下世间的尘劳&#xff0c;大家在一起研究佛法的课程&#xff0c;这件事情在我们的生命当中是非常的稀有难得。 基本上&#xff0c;我们佛法的修习目的是追求身心的安乐…...

markdown变量引用

格式 变量定义通常是路径或网络链接 变量测试...

如何使用echart做K线图

使用ECharts制作K线图需要先引入ECharts的库文件&#xff0c;然后通过调用相应的API来配置和渲染K线图。以下是一个简单的示例代码&#xff1a; // 引入ECharts库文件 <script src"https://cdn.jsdelivr.net/npm/echarts5.0.0/dist/echarts.min.js"></scri…...

Spring Boot应用使用GraalVM本地编译相关配置

1. 介绍 Java应用程序可以通过Graalvm Native Image提前编译生成与本地机器相关的可执行文件。与在JVM执行java程序相比&#xff0c;Native Image占用内存更小和启动速度更快。 从spring boot3开始支持GraalVM Native Image&#xff0c;因此要使用此特性&#xff0c;需要把sp…...

代码的坏味道——长函数

前言&#xff1a;一个函数应该尽量做一件事情&#xff0c;如果非要做多个事情&#xff0c;要做函数提取&#xff0c;每次迭代应该考虑到是否有重复代码或者可以优化的代码。 长函数&#xff1a;长函数的产生&#xff1a; 逻辑是平铺直叙的需求迭代没有考虑优化&#xff0c;一次…...

【机器学习】基于密度的聚类算法:DBSCAN详解

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 基于密度的聚类算法&#xff1a;DBSCAN详解引言DBSCAN的基本概念点的分类聚类过…...

Qt 网络编程 网络信息获取操作

学习目标&#xff1a;网络信息获取操作 前置环境 运行环境:qt creator 4.12 学习内容 一、Qt 网络编程基础 Qt 直接提供了网络编程模块,包括基于 TCP/IP 的客户端和服务器相关类,如 QTcpSocket/QTcpServer 和 QUdpSocket,以及实现 HTTP、FTP 等协议的高级类,如 QNetworkRe…...

基于stm32的通信系统,sim800c与服务器通信,无线通信监测,远程定位,服务器通信系统...

基于stm32的通信系统&#xff0c;sim800c与服务器通信&#xff0c;无线通信监测&#xff0c;远程定位&#xff0c;服务器通信系统&#xff0c;gps&#xff0c;sim800c&#xff0c;心率&#xff0c;温度&#xff0c;stm32 由STM32F103ZET6单片机核心板电路、DS18B20温度传感器电…...

从视频到标签:一条龙搞定YOLOv5自动标注(附OpenCV抽帧与LabelImg修正全流程)

从视频到标签&#xff1a;YOLOv5自动标注全流程实战指南 当你面对数小时的监控视频或行车记录仪素材&#xff0c;需要快速提取其中的车辆、行人等目标时&#xff0c;手动标注每一帧显然不现实。这套基于YOLOv5的自动标注方案&#xff0c;能帮你将标注效率提升10倍以上。下面我将…...

2025.07.15【甲基化】methylKit实战指南:从Bioconductor安装到差异甲基化区域精准注释

1. methylKit&#xff1a;甲基化数据分析的瑞士军刀 第一次接触甲基化数据分析时&#xff0c;我被各种专业术语和复杂流程搞得晕头转向。直到发现了methylKit这个神器&#xff0c;才真正体会到什么叫"一站式解决方案"。作为R语言环境下最成熟的甲基化分析工具之一&a…...

别再死记硬背LFSR了!用Verilog手搓一个伽罗瓦型伪随机数发生器(附完整代码与仿真)

从零构建伽罗瓦LFSR&#xff1a;Verilog实战指南与工程避坑手册 在数字通信系统的测试环节中&#xff0c;工程师常常需要生成特定的数据序列来模拟真实场景。我曾在一个无线模块开发项目中&#xff0c;为了测试接收机的抗干扰能力&#xff0c;需要快速生成符合特定统计特性的伪…...

3步彻底解决FanControl中AMD显卡风扇控制失效问题:ADLXWrapper初始化失败的完整指南

3步彻底解决FanControl中AMD显卡风扇控制失效问题&#xff1a;ADLXWrapper初始化失败的完整指南 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gi…...

pytorch求二维张量转置的几种方法

方法1方法2方法3方法4...

5个核心操作完成HMCL启动器数据无缝迁移:告别重装烦恼

5个核心操作完成HMCL启动器数据无缝迁移&#xff1a;告别重装烦恼 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL 当你的Minecraft世界从一个设备转移到另一个设…...

虚拟电厂之后,最先不够用的为什么是老一套功率预测和经营逻辑?

2026年开年&#xff0c;新能源圈最火的话题是什么&#xff1f;不是组件价格&#xff0c;不是储能成本&#xff0c;而是——虚拟电厂。1月初&#xff0c;江苏省发改委正式印发《关于促进我省虚拟电厂高质量发展的通知》&#xff0c;同步公布全省首批100个虚拟电厂建设项目清单。…...

3步解锁Windows PDF处理新高度:Poppler预编译包深度解析

3步解锁Windows PDF处理新高度&#xff1a;Poppler预编译包深度解析 【免费下载链接】poppler-windows Download Poppler binaries packaged for Windows with dependencies 项目地址: https://gitcode.com/gh_mirrors/po/poppler-windows 你是否还在为Windows平台上复杂…...

如何判断 SEO 排名推广的投资是否值得

SEO 排名推广的投资是否值得&#xff1a;深入分析与实用建议 在当今数字化时代&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;排名推广已成为许多企业获取在线流量和潜在客户的重要手段。面对高昂的SEO推广费用&#xff0c;企业往往会纠结于“这笔投资是否值得”这一问…...