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

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

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


一、父类

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

//父类
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.mrgr.cn/news/33428.html

相关文章:

  • Java的格式化输出
  • 计算机网络笔记001
  • VScode配置连接远程服务器configure ssh Hosts
  • 【计算机网络 - 基础问题】每日 3 题(十八)
  • 轻量化网络 ---- MobileNet V2:Inverted residual with linear bottleneck
  • 笔记整理—内核!启动!—linux应用编程、网络编程部分(3)文件共享与标准IO
  • 二进制和位运算
  • C++模版初阶
  • 初识APC机制实现APC注入
  • 有女朋友后,怎么养成贤内助?为自己找个好伴侣,为孩子找个好妈妈,为母亲找个好儿媳
  • NLP 序列标注任务核心梳理
  • Linux —— 网络基础(一)
  • MySQL锁机制
  • 计算机毕业设计 基于Python的荣誉证书管理系统 Django+Vue 前后端分离 附源码 讲解 文档
  • 详解ps用法
  • 求10000以内n的阶乘(高精度运算)
  • golang学习笔记5-基本数据类型的转换
  • Transcipher:从对称加密到同态加密
  • 部署林风社交论坛/社交论坛linfeng-community遇到问题集合
  • 大数据:驱动企业变革的引擎