函数模版
笔记来源 : 黑马程序员
语法
template<typename T>
声明创建模板<typename 数据类型>
//typename可以用class代替T通常是大写字母
//模板必须要确定出T的数据类型,才可以使用
示例
//函数模板
template<typename T> //声明一个模板, 后面紧跟着使用它
void mySwap(T& a, T& b){
T temp = a;
a = b;
b = temp;
}
void test(){
int a = 10, b = 20;
double c = 1.23, d = 3.23;
//用函数模板实现交换
//两种方式交换
//1.自动类型推导, 必须推导出一致的 数据类型T,才可以使用
mySwap(a, b);
mySwap(c, d);
//2.显式指定类型
mySwap<int>(a, b);
mySwap<double>(c, d);
}
普通函数与函数模板区别:
普通函数调用时可以发生自动类型转换(隐式类型转换)
函数模板调用时,如果利用自动类型推导,不会发生隐式类型转换
如果利用显示指定类型的方式,可以发生隐式类型转换
普通函数和函数模板的调用规则
1.如果函数模板和普通函数都可以实现,优先调用普通函数
2.可以通过空模板参数列表来强制调用函数模板
3.函数模板也可以发生重载
4.如果函数模板可以产生更好的匹配, 优先调用函数模板
//以下情况优先调用普通函数
void swap(int& a, int& b){
int temp = a;
a = b;
b = temp;
}
template<class T>
void swap(T& a, T& b){
T temp = a;
a = b;
b = temp;
}
//以下情况优先调用普通函数
//报错 :无法解析的外部命令, 在链接阶段出现问题,找不到函数的实现体
void swap(int& a, int& b);
template<class T>
void swap(T& a, T& b){
T temp = a;
a = b;
b = temp;
}
//可以通过空模板参数列表, 强制调用函数模压板
//在调用的时候写 MySort<>(a, b)
//以下这种情况调用模板
void mySort(int a, int b){
int t = a;
a = b;
b = t;
}
template<class T>
void mySort(T a, T b){
T t = a;
a = b;
b = t;
}
void test(){
char a = 'a', b = 'b';
mySort(a, b);
}
模板的局限性
有些特定的数据类型需要用具体化的方式做特殊实现, 比如自定义数据类型
//比较两个类是否相等
//1. 重载 == 运算符 (比较麻烦)
//2. 利用具体化Person的版本实现代码
//1. 重载 == 运算符 (比较麻烦)
class Person {
public:
bool operator==(Person p) {
return (this->m_Age == p.m_Age && this->m_Name == p.m_Name);
}
Person(string n, int a) : m_Age(a), m_Name(n) {}
string m_Name;
int m_Age;
};
template<class T>
bool compare(T p1, T p2) {
return p1 == p2;
}
void test() {
Person p1("123", 12);
Person p2("123", 12);
cout << compare(p1, p2) << endl;
}
//2. 利用具体化Person的版本实现代码
class Person {
public:
Person(string n, int a) : m_Age(a), m_Name(n) {}
string m_Name;
int m_Age;
};
template<class T>
bool myCompare(T& p1, T& p2) {
return p1 == p2;
}
template<> bool myCompare(Person& p1, Person& p2)
{
if (p1.m_Age == p2.m_Age && p1.m_Name == p2.m_Name)
return true;
return false;
}
void test() {
int a = 0, b = 0;
cout << myCompare(a, b) << endl;
Person p1("123", 12);
Person p2("123", 12);
cout << myCompare(p1, p2) << endl;
}