模板和泛型编程息息相关,但是大多数人对模板的了解可能只是教材上的一个compare函数,但实际上模板的内容很丰富,学起来也比较抽象,我会结合我所了解的一部分模板内容进行解释。
本文内容参考《C++ Primer》
目录
定义模板
定义模板需要用到template关键字来标识一个模板的开始
语法:template<typename(class) T> 圆括号中的class和typename的作用是相同的,可以使用其中任意一个来定义模板,T为模板的类型名字,也可以定义多个模板名称,例如template<typename T,class U>,意为定义两个模板类型,一个为T,另一个为U
在这行语句的下面我们就可以编写一个模板函数或者一个模板类,需要注意的是,每次定义模板的时候都需要重写这条语句
模板实参推演
在我们调用模板函数的时候,编译器会根据函数中的实参来确定其中的模板参数,这种从函数实参来确定模板实参类型的过程叫做模板实参推演。
template<typename T ,typename U>
bool compare(T a, U b) {
return a > b;
}
int main() {
cout << compare(1.2, 3.4) << endl;
cout << compare(2, 1.3) << endl;
//cout << compare(2, "hello") << endl;
//整形和字符串类型无法比较
return 0;
}
如上述代码,两次函数调用,均通过实参的类型来确定模板的参数类型,需要注意的是,在使用两个模板的时候,函数内部对应的两个参数的操作必须兼容。
也可以指定返回值类型为模板,但是无法通过实参来去确定返回值的类型,所以需要显示的指定返回值类型
template<typename T1 ,typename T2>
T1 func(T2 a) {
return a;
}
int main() {
func<int>(2);
return 0;
}
显示模板的实参按照从左至右的顺序与对应的模板参数匹配,只有最右侧的可以省略,而且他必须可以从函数参数推导过来
template<typename T ,typename U>
U func(T a) {
return a;
}
int main() {
//func<int>(2);
func<int, double>(3);//T对应int U对应double
return 0;
}
可变参数模板
一个可变参数模板就是一个接受可变参数数目的模板函数或模板类,可变数目的参数被称为参数包,存在两种包:模板参数包,表示零个或多个模板参数;函数参数包,表示零个或多个函数参数
语法:template<typename T,typename... Args>,第二个typename后面的三个点表示Args是一个包
template<typename T,typename... Args>
void foo(const T a, const Args ... rest) {
return;
}
int main() {
foo(1, 2, 3, 4, 5, 6);//包中有5个参数
foo(2.0, 'a', 3.4, 'c');//包中有三个参数
foo("nihao");//空包
return 0;
}
根据上面的代码编译器会实例化三个函数
- foo(int, int, int, int, int, int)
- foo(double, char, double, char)
- foo(char*)
可见T的类型又传入的实参进行推导,后面的类型
模板特例化
编写一个模板时,不可能做到对每一种类型都能很好的适配,所以有些数据类型的操作,需要进行特殊处理,这时就有了模板的特例化版本,比如compare函数,如果传入的是两个字符指针,我们想要比较的是两个字符串的大小,而直接返回 return a>b;比较的则是两个指针地址的大小,不符合我们的需求,所以我们需要对char* 进行特例化
#include<iostream>
using namespace std;
template<typename T>
bool compare(const T a,const T b) {
cout << "compare" << endl;
return a > b;
}
template<>
bool compare(const char* a, const char* b) {
cout << "compare<char*>" << endl;
return strcmp(a,b);
}
int main() {
cout << compare(2, 3) << endl;
const char* p1 = "nihao";
const char* p2 = "hello";
cout << compare(p1, p2) << endl;
return 0;
}
上述代码在执行过程中,第一个compare用普通版本,第二个compare用特例化版本
以上仅仅是对模板简单的一些使用,如有问题,欢迎大家批评指正。
标签:return,int,C++,参数,template,教材,实参,模板 From: https://blog.csdn.net/weixin_58234579/article/details/143630162