C++
C++
目录
可变参数模板 Variadic Templates
本篇参考:
可变参数函数
三个点...的写法以前就有,但不是在模板里
printf 源码
int __cdecl printf (
	const char *fromat,
	...	// 可以接受任意变量
	)
{
    // ...
}可变参数模板
可变参数模板 函数递归
例程 - print
/** 模板代码 */
void print()
{
    
}
template <typename T, typename... Types>
void print(const T& firstArg, const Types&... args)	// 表示参数的类型和数目都可变
{
    cout << firstArg << endl;
    print(args...);
}
/** 使用代码 */
print(7.5, "hello", bitset<16>(377), 42);
/* 输出:
7.5
hello
0000000101111001(16bit来表示377)
42
*/Q:
template <typename T, typename... Types>
void print(const T& firstArg, const Types&... args){/**/}
// 和
template <typename... Types>
void print(const Types&... args){/**/}
// 可以共存吗
// 若可,谁比较泛化、谁比较特化A:
// 可以共存
// 优先使用比较特化的那个版本,即
template <typename T, typename... Types>
void print(const T& firstArg, const Types&... args){/**/}
// 的版本原理
...就是一个pack包
- 用於template parameters,就是template parameters pack(模板参数包)
 - 用於function parameter types,就是function parameter types pack(函数参数类型包)
 - 用於function parameters,就是function parameters pack(函数参数包)
 
可以帮助我们做递归,以上述例程为例:
(7.5, "hello", bitset<16>(377), 42)传入后会被分割成两块firstArg = 7.5,args = ("hello", bitset<16>(377), 42)
然后重复这个过程递归调用,当args为0时,就调用print()的重载版本
优先级
类
class CustomerHash{
public:
    std::size_t operator()(const Customer& c) const {
        return hash_val(c.fname, c.lname, c.no)		// 调用【版本1】(只有版本1符合)
    }
};可变参数模板函数的重载
// 【版本1】
template <typename... Type>
inline size_t hash_val(const Types&... arg){		// 接受一个参数
    size_t seed = 0;
    hash_val(seed, args...);						// 调用【版本2】(版本1、2、3均符合)
    return seed;
}
// 【版本2】
template <typename T, typename... Types>
inline void hash_val (size_t& seed,
		const T& val, const Types&... args) {		// 接受三个参数
    hash_combine(seed, val);
	hash_val(seed, args...);						// 调用【版本2】,递归到最后调用【版本3】
}
// 【版本3】
template<typename T>
inline void hash_val(size_t& seed, const T& val) {	// 接受两个参数
    hash_combine(seed, val);
}
#include <functional>
template <typename T> 
inline void hash_combine(size_t& seed, const T& val){
	seed ^ = std:hash<T>O(val) + 0x9e3779b9
		+ (seed<<6) +(seed>>2);
}可变参数模板 类递归
例程 - tuple
tuple头文件
template<typename... Values> class tuple;
template<> class tuple<>{};tuple代码
template<typename Head, typename... Tail>
class tuple<Head,Tail...> :private tuple<Tail...> 	// 方便递归,自己继承自己【绝了,妙啊】
{
    typedef tuple<Tail...> inherited;
public:
	tuple(){ }
	tuple(Head v, Tail... vtail)
        :m_head(v), inherited(vtail...){}			// initialization list【关键】抽出来的部分定义为成员变量,其他部分给父类
    typename Head::type head(){ return m_head; }
    inherited& tail(){ return *this; }				// 返回指针
protected:
	Head m_head;
};调用代码
tuple<int, float, string> t(41, 6.3, "nico");
t.head();			// 获得41
t.tail().head();	// 6.3应用
应用方向
可变参数模板主要用于递归
可以很方便地完成 recursive function call(递归函数调用)
在标准库中的使用
(详见C++11标准库一节)
链接到当前文件 0
没有文件链接到当前文件