第四章 可变参数模板

1.什么是模板可变参数? 可变模板参数就是模板参数可以接受没有规定数量的参数

2.简单的例子

void print() {//这个是给一个递归的结束标志

}
template<typename T, typename ...Types>void print(T t,Types... args) {
	std::cout << t << std::endl;
	print(args...);
}

3.另一种写法

template<typename T>void print(T arg){
    std::cout<<arg<<std::endl;
}
template<typename T,typename ...Types>void print(T arg,Types... Args){
    print(arg);
    print(Args...);
    
}

4.sizeof...测量一个参数包的数量

template<typename ...Types>void func(Types... args) {
	//if constexpr (sizeof...(args) > 0) {
	//	std::cout << t << std::endl;
	//	func(args...)
	//}
	std::cout << sizeof...(args) << std::endl;
	std::cout << sizeof...(Types) << std::endl;
}

5.折叠表达式

//例子1累加
pack op ... (pack1 op(...pack2(packN-1 op packN)))
... op pack ((pack1 op pack2) op pack3...) 
template<typename ...S>void Sum(S... s) {
	std::cout << (s+ ...) << std::endl;
}
//例子2 打印每一个变量
template<typename T, typename...Args>void Print(T t, Args...args) {
	(std::cout << ... << args) << '\n';
}

//
例子3
template<typename T, typename...Args>void Print(T t, Args const&...args) {
	(std::cout << ... << args) << '\n';
}
template<typename T>class AddSpace {
public:
	T const& ref;
	AddSpace(T const& ref) :ref(ref) {
	}
	friend std::ostream& operator<<(std::ostream& os, AddSpace<T> s) {//这个地方也可以用&&临时变量是个右值
		return os << s.ref<<' ';
	}

};
template<typename T>void f(T t) {
	std::cout << AddSpace(t);
}
template<typename ...Args>void f(Args ...args) {
	(std::cout << ... << AddSpace(args));

}

6.可变参数表达式

//例子1
template<typename ...Types>void Sam(Types... args) {
	print(args + args...);
}
//例子2
template<typename ...Types>void AddOne(Types... args) {
	print(1 + args...);
	print((1 + args)...);
}
//例子3
template<typename T, typename ...Types>bool Test(T t,Types...Args) {
	return (std::is_same_v<T, Types> && ...);
	
}

7.可变参数下标

template<typename T, typename...Indices>void printIndice(const T&t, Indices...index) {
	print(t[index]...);
}