C++11 可变参模板

可变参函数模板

概述

可变参数模版(variadic templates)是C++11新增的最强大的特性之一,它对参数进行了高度泛化,它能表示0到任意个数、任意类型的参数。

格式

	template <typename... T>
	void fuc(T... args) 
	{
		std::cout << sizeof...(args) << std::endl;   //sizeof...可变参数量
	}

可变参数包的若干展开方式

1、递归继承方式展开可变参数包

//code

namespace ParsesVariadicByInheritance
{
	template<typename ...Args>
	class xhVariadicTemplates;//主模板

	template<>
	class xhVariadicTemplates<>
	{
	public:
		xhVariadicTemplates()
		{
			std::cout <<"type: "<<typeid(void).name() << std::endl;
		}
	};

	template<typename Head, typename ... Tail>
	class xhVariadicTemplates<Head, Tail ...> :private xhVariadicTemplates<Tail ...>
	{
	public:
		xhVariadicTemplates(Head head, Tail ... tail) :xhVariadicTemplates<Tail ...>(tail ...)
		{
			std::cout << "type: "<<typeid(std::declval<Head>()).name() <<"\t value: "<< head << std::endl;
		}
	};
}
//test

int main()
{
	ParsesVariadicByInheritance::xhVariadicTemplates<int, double, float,std::string> obj(12,12.12,12.12f,"xu");

	return 0;
}
//output

type: void
type: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >    value: xu
type: float      value: 12.12
type: double     value: 12.12
type: int        value: 12

2、递归组合方式展开可变参数包

//code

namespace ParsesVariadicByComposition
{
	template<typename ...Args>
	class xhVariadicTemplates;//主模板

	template<> 
	class xhVariadicTemplates<>
	{
	public:
		xhVariadicTemplates()
		{
			std::cout << "type: " << typeid(void).name() << std::endl;
		}
	};

	template<typename Head, typename ... Tail>
	class xhVariadicTemplates<Head, Tail ...> //: private myclasst<Others...> //偏特化
	{
	public:
		xhVariadicTemplates(Head head, Tail ...tail) :mHead(head), mTail(tail...) //, myclasst<Others...>(paro...)
		{
			std::cout << "type: " << typeid(std::declval<Head>()).name() << "\t value: " << head << std::endl;
		}
		Head mHead;
		xhVariadicTemplates<Tail...> mTail; //组合关系
	};

}
//test

int main()
{
	ParsesVariadicByComposition::xhVariadicTemplates<int, double, float,std::string> obj(12,12.12,12.12f,"xu");

	return 0;
}
//output

type: void
type: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >    value: xu
type: float      value: 12.12
type: double     value: 12.12
type: int        value: 12

3、通过tuple和递归调用展开参数包

//code

namespace ParsesVariadicByTuple
{
	//实现思路:计数器从0开始,每处理一个参数,计数器+1,一直到把所有参数处理完。模板偏特化,作为递归调用结束;

	//currentCount用于计数,从0开始,maxCount表示参数数量
	template<int currentCount, int maxCount, typename...T>
	class xhVariadicTemplates
	{
	public:
		static void parsesFuc(const std::tuple<T...>& t)
		{
			std::cout << "type: " << typeid(std::get<currentCount>(t)).name() << "\t value: " << std::get<currentCount>(t) << std::endl;
			xhVariadicTemplates<currentCount + 1, maxCount, T...>::parsesFuc(t); //递归调用
		}
	};
	//特化版本,用于结束递归调用
	template <int maxCount, typename...T>
	class xhVariadicTemplates< maxCount, maxCount, T...>
	{
	public:
		static void parsesFuc(const std::tuple<T...>& t)	{}
	};

	template <typename...T>
	void parsesFuc(const std::tuple<T...>& t)  //可变参函数模板
	{
		xhVariadicTemplates<0, sizeof...(T), T...>::parsesFuc(t);
	}
}
//test

int main()
{
	using namespace std::literals::string_literals;
	ParsesVariadicByTuple::parsesFuc(std::make_tuple(12, 12.12, 12.12f, "xu"s));
	
	return 0;
}
//output

type: int        value: 12
type: double     value: 12.12
type: float      value: 12.12
type: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >    value: xu

4、通过逗号表达式展开参数包

逗号表达式在C++中有这样的特性:(A,B,C),则从左到右求值,最后C的(返回)值作为整个表达式的值。

//code

namespace ParsesVariadicByCommaExpression
{
	template <typename T>
	int printArg(T t)
	{
		std::cout << "type: " << typeid(t).name() << "\t value: " << t << std::endl;
		return 0;
	}

	template <typename ...Args>
	void parses(Args... args)
	{
		int array[] = { (printArg(args), 0)... };
	}
}
//test

int main()
{
	using namespace std::literals::string_literals;
	ParsesVariadicByCommaExpression::parses(12, 12.12, 12.12f, "xu"s);
	
	return 0;
}
//output

type: int        value: 12
type: double     value: 12.12
type: float      value: 12.12
type: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >    value: xu

原理:
通过初始化列表来初始化一个变长数组, { (printArg(args), 0)… }将会展开成((printarg(arg1), 0), (printarg(arg2), 0), (printarg(arg3), 0),…);
parses函数中的逗号表达式:(printArg(args), 0),先执行printArg(args)输出参数,再得到逗号表达式的结果0。最后生成一个元素值都为0的,长度为sizeof…(Args)的数组。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值