可变参模板和模板模板参数

举报
无敌清风蓝 发表于 2023/08/31 22:09:00 2023/08/31
【摘要】 可变参模板和模板模板参数

1.可变参模板和模板模板参数

前面学的函数模板和类模板,其中的模板参数都是固定的,在C++11中引入了可变参模板,这种可变参模板允许模板定义中含有0到多个(任意个)模板参数,比传统模板不一样,多了一个…符号,这个符号是省略号

1.1.可变参函数模板

1)例子


template<typename... T>
void myfunc(T... args)  //T:一包类型  args:一包形参
{
    cout << sizeof...(args) << endl; //sizeof...属于固定语法,用在可变参模板内部,用来表示收到的模板参数个数,只能针对这种...的可变参
    cout << sizeof...(T) << endl; //和上行效果一样
}
在main
myfunc(); //0
myfunc(10,20); //2
myfunc(10,20.5,"abcx",68); // 4

(1)一般把上面的 args 称为一包或者一堆参数,而且每个参数的类型可以各不相同。所以理解T这个名字的时候,不能把它理解成一个类型,而是要理解成0到多个不同的类型
(2)这包参数中可以容纳0个到多个模板参数,而且这些模板参数可以为任意的类型
(3)注意,名字要理顺一下:
代码行 void myfunctl(T…args)中,因为T后面带了“…”,所以将T称为“可变参类型”,看起来是一个类型名,实际上里面包含的是0到多个不同的类型(一包类型)

args:可变形参,既然T代表的是一包类型,那显然 args 代表的是一包形参

2)参数包展开

获得这一包参数后,怎么逐个拿到手处理呢,一般展开的套路是固定的,用递归的方式,要求在代码编写里有一个参数包展开函数和一个同名的递归终止函数,通过这两个函数把参数包展开

一般为了参数包展开方便,会把可变参数函数模板写成上面myfunc的样子,就是有这两条

  • 有单独的参数
  • 后面跟一个“一包参数”

实例:

1)参数包展开函数

template<typename T, typename... U>
void myfunc(const T& firstarg, const U& ...otherargs)
{
    cout << "收到的参数值是:" << firstarg << endl;
    myfunc(otherargs...) //递归调用,注意塞进来的是一包形参,省略号不能省略
}

2)一个同名的递归终止函数(是一个函数,不是函数模板),一般带0个参数的同名函数,就是递归终止函数,这个递归终止函数放在刚才myfunc可变参函数模板的上面位置

//因为参数是被一个个剥离的,剥离到最后,参数个数就是0个,所以此时就会调用这个版本的myfunc()
void myfunc()
{
    cout << "参数包展开时执行了递归终止函数myfunc2()" << endl;
}

1.2.可变参类模板


太麻烦了,以后再填坑,一般也用不到

1.3.模板模板参数

就是把原来模板参数搞成一个模板

template<typename T>

T是一个类型,比如int,或者各种的,但现在这个T,本身也是一个模板了

template<
	typename T,
	template<class> class Container //这里Container叫U也行,只不过一般模板模板参数当容器用,所以这取名是Container
>        
class myclass
{
public:
	T m_i;   
    Container<T> myc;
}

Container当作一个类模板来用了,因为后面带着<T>,所以它是一个类模板

从整体看

template<class> class Container 是myclass这个类模板的模板参数
而Container本身也是一个模板,所以Container的完整名字就叫做模板模板参数

记得还有这种写法

template<
	typename T,
	//template<class> class Container
	template<typename W> typename Container //W没用,可以省略 
>    
class myclass
{
    
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。