1.变长模板
1.1…变长模板定义
支持不限制数量的模板参数
// tuple是一个模板类
// 模板形参:可变数量的类型
template
class tuple{}
tuple a;
// NonTypeVar是一个模板类
// 模板形参:可变数量的int类型数值
template
class NonTypeVar{};
NonTypeVar<1, 0, 2> aa;
1.2.变长模板使用
(1).使用模板参数包
#include
// B是一个模板类
// 模板形参:两个类型
template
class B {
};
// B是一个特化的模板类
// 模板形参:int,double
template <>
class B {
public:
B() {
printf("B\n");
}
};
// Temp是一个模板类
// 模板形参:可变数量的类型
// A...代表对typename... A为代表的部分的一个引用。
template
class Temp:private B {
};
// 这个xy将私有继承B
Temp xy;
int main(){
return 0;
}
#include
// tuple是一个模板类
// 模板形参:可变个数类型
template
class tuple{
public:
tuple(){
printf("normal\n");
}
};
// tuple是一个特化模板类
// 模板形参:可变个数类型。从第二到最后一个类型可通过Tail...来整体引用
template
class tuple:private tuple{
public:
tuple(){printf("sizeof_%d\n", sizeof(Head));}
Head h;
};
// tuple<>是一个特化模板类
// 模板形参:空
template<>
class tuple<>{
public:
tuple(){
printf("null\n");
}
};
tuple a;
int main(){
return 0;
}
#include
using namespace std;
template
struct Multiply{};
template
struct Multiply{
static const long val = first * Multiply::val;
};
template<>
struct Multiply<>{
static const long val = 1;
};
int main(){
cout << Multiply<2,3,4,5>::val << endl;
return 0;
}
// f是一个模板函数
// 函数形参:可变个数类型的变量
template
void f(T... args){
}
int main(){
f(1, 1.0);//实例化为f(int a, double b)
f(1);//实例化为f(int)
}
利用模板参数包,函数参数包可实现c的变长函数的一个实例
#include
#include
using namespace std;
void Printf(const char* s){
while(*s){
if(*s == '%' && *++s != '%'){
throw runtime_error("invalid format string: missing arguments");
}
cout << *s++;
}
}
// Printf是一个模板函数
// 函数形参:首个参数必须是const char*,第二个参数必须是某个类型,第三到最后为可变数量个类型
template
void Printf(const char* s, T value, Args... args){
while(*s){
if(*s == '%' && *++s != '%'){
cout << value;
return Printf(++s, args...);
}
cout << *s++;
}
throw runtime_error("extra arguments provided to Printf");
}
int main(){
Printf("hello %s\n", string("world"));
return 0;
}
c的可变参数函数printf必须依赖对格式化字符串的解析,来提取每个可变参数。
借助可变参数模板,可以不依赖格式化字符串,借助模板类型推导,可变参数包来依次得到每个模板参数的类型和实参。
(4).使用参数包时允许添加修饰符
#include
using namespace std;
template
void DummyWrapper(T... t){
}
template
T pr(T t){
cout << t;
return t;
}
// VTPrint是一个模板函数
// 函数形参:可变数量的类型
template
void VTPrint(A... a){
// 通过a...可以整体引用A... a
// 通过pr(a)...,相当于整体引用A... a时,对其中每个元素t引用的是pr(t)
DummyWrapper(pr(a)...);
}
int main(){
VTPrint(1, ", ", 1.2, ", abc\n");
cout << endl;
return 0;
}