【模板进阶】类模板中可变参的特殊继承方式

本篇博客主要介绍在类模板中可变参数的特殊继承方式和展开方式。 回顾之前的可变参展开:可变参模板


一、父类

首先,我们有一个父类,是一个可变参类模板,如下:

//父类
template<typename...Args>
class myclass {
public:myclass() {std::cout << "myclass::myclass()执行了,可变参个数为:" << sizeof...(Args) << "\n";}
};

下面我们开始对它的特殊继承进行讨论。


二、 m y c l a s s < A r g . . . > myclass<Arg...> myclass<Arg...>继承

参考下方代码:

//myclass<Args...>继承
template<typename... Args>
class myclass2 :public myclass<Args...> {
public:myclass2() {std::cout << "myclass2::myclass2()执行了,可变参个数为:" << sizeof...(Args) << "\n";}};

像这样的继承方式,在参数范围上与父类一样。例如,下面的代码:

myclass2<double, float, int> myc2;

将会实例化出一个 m y c l a s s < d o u b l e , f l o a t , i n t > myclass<double,float,int> myclass<double,float,int>的父类和 m y c l a s s 2 < d o u b l e , f l o a t , i n t > myclass2<double,float,int> myclass2<double,float,int>的子类。调用结果如下:

在这里插入图片描述


三、 m y c l a s s < A r g > . . . myclass<Arg>... myclass<Arg>...继承

这样的继承方式可以看做是多继承,具体上,这是继承的一个基类参数包,可以参考:基类参数包的展开这篇博客,讲的比较清晰。

由于是多继承,那自然会实例化出多个父类。比如下面的代码:

//myclass<Args>..继承
template<typename... Args>
class myclass3 :public myclass<Args>...{
public:myclass3() {std::cout << "myclass3::myclass3()执行了,可变参个数为:" << sizeof...(Args) << "\n";}
};

这里会实例化出 m y c l a s s < d o u b l e > , m y c l a s s < f l o a t > , m y c l a s s < i n t > myclass<double>,myclass<float>,myclass<int> myclass<double>,myclass<float>,myclass<int>三个父类模板,通过递归的方式逐步展开

myclass3<double, float, int> myc3;

可以发现,实例化出了三个父类模板,和一个子类模板:

在这里插入图片描述


四、 m y c l a s s < A r g , c h a r > . . . myclass<Arg,char>... myclass<Arg,char>...继承

这种继承方式和上一中类似,只不过指定了增加一个 c h a r char char类型的参数,同样会实例化出多个父类模板。
参考下面的代码:

//myclass<Arg,char>继承
template<typename... Args>
class myclass4 :public myclass<Args, char>...{
public:myclass4() {std::cout << "myclass4::myclass4()执行了,可变参个数为:" << sizeof...(Args) << "\n";}};

这将实例化出 m y c l a s s < d o u b l e , c h a r > , m y c l a s s < f l o a t , c h a r > , m y c l a s s < i n t , c h a r > myclass<double,char>,myclass<float,char>,myclass<int,char> myclass<double,char>,myclass<float,char>,myclass<int,char>三个父类,和 m y c l a s s 4 < d o u b l e , f l o a t , i n t , c h a r > myclass4<double,float,int,char> myclass4<double,float,int,char>的一个子类。

myclass4<double, float, int> myc4;

在这里插入图片描述
这里显示可变参数为 3 3 3不包括 c h a r char char类型,因为它不属于可变参数里面,所以实际上这里还是四个参数。


五、 m y c l a s s < A r g s , A r g s . . . > . . . myclass<Args,Args...>... myclass<Args,Args...>...继承

这种继承方式,前一个参数是 A r g s Args Args只有一个参数,而后一个参数 A r g s . . . Args... Args...是一个参数包,而最后又用一个 . . . ... ...表示继承的是参数包,因此这里会实例化出多个父类。

//myclass<Args,Args...>...继承
template<typename... Args>
class myclass5 :public myclass<Args, Args...>...{
public:myclass5() {std::cout << "myclass5::myclass5()执行了,可变参个数为:" << sizeof...(Args) << "\n";}};

下方的代码将实例化出 m y c l a s s < d o u b l e , d o u b l e , f l o a t , i n t > , m y c l a s s < f l o a t , d o u b l e , f l o a t , i n t > , m y c l a s s < i n t , d o u b l e , f l o a t , i n t > myclass<double,double,float,int>,myclass<float,double,float,int>,myclass<int,double,float,int> myclass<double,double,float,int>,myclass<float,double,float,int>,myclass<int,double,float,int>这个三个父类,和 m y c l a s s 5 < d o u b l e , f l o a t , i n t > myclass5<double,float,int> myclass5<double,float,int>这个子类

myclass5<double, float, int> myc5;

运行结果:

在这里插入图片描述


六、 m y c l a s s < A r g . . . , A r g . . . > myclass<Arg...,Arg...> myclass<Arg...,Arg...>继承

与第一种继承类似,只不过把参数列表复制了一遍。参考下方代码:


//myclass<Args...,Args...>继承
template<typename... Args>
class myclass6 :public myclass<Args..., Args...> {
public:myclass6() {std::cout << "myclass6::myclass6()执行了,可变参个数为:" << sizeof...(Args) << "\n";}
};

这将实例化出 m y c l a s s < d o u b l e , f l o a t , i n t , d o u b l e , f l o a t , i n t > myclass<double,float,int,double,float,int> myclass<double,float,int,double,float,int>六个参数的父类。

myclass6<double, float, int> myc6;

如图:

在这里插入图片描述


七、 m y c l a s s < A r g , A r g > . . . myclass<Arg,Arg>... myclass<Arg,Arg>...继承

这种继承方法和 m y c l a s s < A r g > . . . myclass<Arg>... myclass<Arg>...类似,只不过是实例化出的模板参数复制了一遍,同样也是多继承。参考下方代码:

//myclass<Args,Args,Args...>...继承
template<typename... Args>
class myclass9 :public myclass<Args,Args>...{
public:myclass9() {std::cout << "myclass9::myclass9()执行了,可变参个数为:" << sizeof...(Args) << "\n";}};

这将实例化出 m y c l a s s < d o u b l e , d o u b l e > , m y c l a s s < f l o a t , f l o a t > , m y c l a s s < i n t , i n t > myclass<double,double>,myclass<float,float>,myclass<int,int> myclass<double,double>,myclass<float,float>,myclass<int,int>这个三个父类。

myclass9<double, float, int> myc9;

如下图:

在这里插入图片描述


八、总结:

对于可变参类模板的继承方式总结起来就两种,其他方式可以看做是这两种方式的排列组合。

( 1 ) (1) (1)形如 t e m p l a t e < A r g s . . . > template<Args...> template<Args...>的单继承

( 2 ) (2) (2)形如 t e m p l a t e < A r g s > . . . template<Args>... template<Args>...的多继承


继承的时候可以对这两种类型进行排列组合,也可以指定增加其中一个类型,如 c h a r char char类型等。
注意, t e m p l a t e < A r g s . . . > template<Args...> template<Args...>可以有多个,而 t e m p l a t e < A r g s > . . . template<Args>... template<Args>...只能有一个。

即如下的是合法的:
t e m p l a t e < A r g s , A r g s . . . , A r g s . . . , A r g s . . . > . . . template<Args,Args...,Args...,Args...>... template<Args,Args...,Args...,Args...>...

而多继承一定要配合 A r g s Args Args来使用,即 t e m p l a t e < A r g s . . . > . . . template<Args...>... template<Args...>...是非法的!

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

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

相关文章

windows cuda12.1 pytorch gpu环境配置

安装cuda12.1 nvcc -V conda创建pythong3.10环境 conda create -n llama3_env python3.10 conda activate llama3_env 安装pytorch conda install pytorch torchvision torchaudio pytorch-cuda11.8 -c pytorch -c nvidia gpu - Pytorch version for cuda 12.2 - Stack Ov…

MySQL面试不翻车指南:轻松掌握数据库秘籍

写在前面 &#x1f525;我把后端Java面试题做了一个汇总&#xff0c;有兴趣大家可以看看&#xff01;这里&#x1f449; ⭐️在无数次的复习巩固中&#xff0c;我逐渐意识到一个问题&#xff1a;面对同样的面试题目&#xff0c;不同的资料来源往往给出了五花八门的解释&#…

大屏幕导入名单电话等数据滚动抽奖制作教程_姓名电话号码数字滚动抽奖产品

原文地址 在当今数字化时代&#xff0c;抽奖活动也紧跟潮流&#xff0c;不断进行创新。导入数据滚动抽奖产品就是其中一种令人耳目一新的抽奖方式&#xff0c;它不仅提高了抽奖的公平性和透明度&#xff0c;还给参与者带来了全新的体验。导入数据滚动抽奖产品的优势&#xff1a…

[Linux]常用操作指令

实用指令 1.指定运行级别 查看当前运行级别 切换运行级别 设置默认运行级别 2.找回root密码 3.帮助指令 查看ls命令的帮助信息 列出文件, 包含隐藏文件 单行展示信息 命令可以组合使用 获得cdn内置命令的帮助信息 4.文件目录指令 5.组管理和权限管理 所有者 所在组

鸿蒙 WebView 如何 Debug

前置&#xff1a; hdc chrome //----------------------------------------------------------------------------------------------- hdc shell cat /proc/net/unix | grep devtools 0: 00000002 0 10000 1 1 81134005 webview_devtools_remote_62479exit执行&…

【java面经速记】Mysql和ES数据同步

目录 Mysql业务数据库 ES查询数据库 数据同步方案 同步双写 异步双写&#xff08;MQ方式&#xff09; 基于Mysql的定时扫描同步 基于Binlog实时同步 使用canal监听binlog同步数据到es&#xff08;流行方案&#xff09; 拓展:mysql的主从复制原理 canal原理&#xff1a…

通信工程学习:什么是NFVI网络功能虚拟化基础设施层

NFVI&#xff1a;网络功能虚拟化基础设施层 NFVI&#xff08;Network Functions Virtualization Infrastructure&#xff09;即网络功能虚拟化基础设施层&#xff0c;是NFV&#xff08;Network Functions Virtualization&#xff0c;网络功能虚拟化&#xff09;架构中的一个重要…

PS相关操作记录

1. 磨皮步骤 1.1. 图层操作 先对照片进行去瑕疵、液化等操作&#xff0c;操作完的图层&#xff0c;重命名为液化&#xff0c;方便识别。复制两个图层&#xff0c;分别改为“低频”、“高频”&#xff0c;低频在下&#xff0c;高频在上。选中“低频”图层&#xff0c;滤镜 -&g…

midjourney 网页版收费页面

网页版体验了一个月&#xff0c;感觉确实方便很多 midjourney 网页版地址https://www.midjourney.com/archive 主要是左下角进行相关设置 付费以后&#xff0c;记得在edit里面取消续费&#xff0c;取消后如图所示&#xff0c;我这个月用完&#xff0c;这个时间是即时的&…

嵌入式C语言自我修养:GNU C编译器扩展语法精讲

在Linux内核的源码中&#xff0c;你会发现许多这样的“奇特”代码。它们看起来可能有点陌生&#xff0c;但它们实际上是C语言的一种扩展形式&#xff0c;这种扩展在C语言的标准教材中往往不会提及。这就是为什么你在阅读Linux驱动代码或内核源码时&#xff0c;可能会感到既熟悉…

java sdk下载,解决下载了java但是编译不了

直接搜Java得到的网站使用不了的 应该只是个功能包或者版本太低用不了 得去oracle公司搜java这个产品去下载

MySQL中去除重复

除去相同的行 SELECT DISTINCT 列名 FROM 表名; 示例&#xff1a;查询employees表&#xff0c;显示唯一的部门ID select distinct department_id from employees;

心理教育辅导系统:Spring Boot技术实现

4 系统设计 4.1系统概要设计 高校心理教育辅导系统主要分为管理员、教师和学生三个角色&#xff0c;系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet&#xff0c;便可以在任…

论文阅读:Omni-Kernel Network for Image Restoration

论文地址&#xff1a;https://ojs.aaai.org/index.php/AAAI/article/view/27907 项目地址&#xff1a;https://github.com/c-yn/OKNet 发表时间&#xff1a;2024 图像恢复的目的是从一个退化的低质量的观测中重建一个高质量的图像。最近&#xff0c;Transformer模型由于其强大…

本地快速部署一个简洁美观的个人Halo博客网站并发布公网远程访问

文章目录 前言1. Docker部署Halo1.1 检查Docker版本如果未安装Docker可参考已安装Docker步骤&#xff1a;1.2 在Docker中部署Halo 2. Linux安装Cpolar2.1 打开服务器防火墙2.2 安装cpolar内网穿透 3. 配置Halo个人博客公网地址4. 固定Halo公网地址 前言 本文主要介绍如何在Cen…

[系列]参数估计与贝叶斯推断

系列 点估计极大似然估计贝叶斯估计&#xff08;统计学&#xff09;——最小均方估计和最大后验概率估计贝叶斯估计&#xff08;模式识别&#xff09;线性最小均方估计最小二乘估计极大似然估计&贝叶斯估计极大似然估计&最大后验概率估计线性最小均方估计&最小二乘…

【鸿蒙开发 day13】

ArkTs-核心-基础 一.处理数据1.字符串的拼接2.模板字符串 二.类型转换(1)字符串转数字(2)数字转字符串(3)布尔值转换情况 三.交互点击事件四.状态管理五.隐藏图片案例六.运算符1.算数运算符2.赋值运算符3.一元运算符4.比较运算符5.逻辑运算符6.运算符优先级 七.美团点餐案例八.…

游戏开发团队并非蚂蚁协作(3):开发过程中的“尾气”

“尾气”指的什么&#xff1f; 就像汽车虽然行驶到达目的&#xff0c;但是却会在路途中留下尾气污染环境。开发过程中有时虽然完成了需求&#xff0c;但是也留下了“尾气”&#xff0c;或者说“技术债”、“遗留问题”。 “尾气”并不是看不到或者难以被解决&#xff0c;而是…

【Linux】常用指令详解一(ls,-a,-l,-d,cd,pwd,mkdir,touch,rm,clear)

1.前言 读了一些Linux常用指令的博文&#xff0c;很可惜没读到一点点手把手教怎么操作的博文&#xff0c;所以写一篇手把手教适合初学者的Linux常用指令博文 Linux的命令是树状结构 输入这一句命令&#xff1a;yum install -y tree 即可以查看Linux树状目录结构 查看示例&am…

2024年中国研究生数学建模竞赛C题“数据驱动下磁性元件的磁芯损耗建模”全析全解

↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 总领这个题&#xff0c;是属于数据挖掘和数据优化类型的题目&#xff…