C++11新特性数量不定的模板参数

Posted 老虎中的小白Gentle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++11新特性数量不定的模板参数相关的知识,希望对你有一定的参考价值。

什么叫数量不定的模板参数呢?请看下面的例子

#include <iostream>
using namespace std;

void print()//递归的出口
{
   //空实现
}

template<typename T, typename... Types>
void print(const T& firstArg, const Types&... args)
{
	cout << firstArg << endl;
	print(args...); //递归
}

int main()
{

	print(7.5, 'A', "Hello", 100);

	return 0;
}

程序运行的结果为:
在这里插入图片描述
这符合你的想法吗?

这里的…是关键字

…就是一个所谓的包
用于模板参数,就是模板参数包,如下

template<typename T, typename... Types> //这里...在Types前是语法规定的

用于函数参数类型,就是函数参数类型包,如下

void print(const T& firstArg, const Types&... args)//这里...在Types后是语法规定的

用于函数参数,就是函数参数包,如下

print(args...); 

对于print函数的解释

print(7.5, 'A', "Hello", 100);

把参数分成两部分,第一个参数7.5,和一个包(‘A’, “hello”, 100)。
然后在print函数里面再递归调用自己,第一参数是’A’,和一个包(“hello”,100)。
到后面一个参数,和一个包,包是没有参数的。在函数内部再调用print的时候已经没有参数了,就不递归了,调用第一个print(所以这里就是递归的出口)。

在可变参数模板中,你可以用sizeof…(args)查看参数的个数。

cout << "sizeof: "<<sizeof...(args) << endl;

那如果同时存在多个参数数量不定的模板时如下,那到底是调用哪个呢?与上面的print能否共存?哪个比较特化,哪个比较泛化?

template<typename ...Types>
void print(const Types&... args)
{
	cout << "调用我吗?" << endl;
}

在以上的printf中,调用的是前面的那个,没有报错证明共存,因为调用了前面的那个,所以它比较特化。

看看下面的两个标准库例子,加深对于数量不定的模板参数的理解和应用

例子1函数:
在这里插入图片描述
图中的箭头标明调用哪个函数,先找特化,没有就再找泛化去调用的。

例子2类:它的精髓在于

template<typename Head, typename... Tail>
class tuple<Head,Tail...>:private tuple<Tail...>

在这里插入图片描述

以上是关于C++11新特性数量不定的模板参数的主要内容,如果未能解决你的问题,请参考以下文章

C++11新特性:8—— C++11支持函数模板的默认模板参数

C++11新特性:9—— C++11在函数模板和类模板中使用可变参数

C++11新特性从using化名模板到模板模板参数

C++11 ——— 可变参数模板

C++11 ——— 可变参数模板

C++不定参数