函数模板:
找到函数相同的实现思路,区别于函数的参数类型。
使用函数模板使得函数可容纳不同类型的参数实现函数功能,而不是当类型不同时便编译大量类型不同的函数,产生大量重复代码和内存占用
函数模板格式:
template<typename T, typename T2...>
函数返回值类型 函数名(模板形参表)
{//函数主体;//...
}
格式说明:
- template:声明函数模板的关键字;
- typename: 模板类型关键字(”class“亦可),后+ 模板类型名;
- T:通用类型名
- <>:可容纳多个类型参数,中间逗号隔开,参数数量与模板函数参数一致;
举例:
#include <iostream>
#include <string>
using namespace std;template<typename T, typename T2>
int compare(const T& a, const T2& b)
{if (a > b)return 1;else if (a == b)return 0;else return -1;
}
int main()
{int a = 4;int b = 5;cout <<"compare(a,b):"<< compare(a, b) << endl;cout<<"compare(4,5.5):"<<compare(4, 5.5) << endl;cout <<"compare(111, 5.4):"<< compare(111, 5.4) << endl;string c = "abc";string c1 = "abc";string d = "def";cout <<"string 比较:"<< compare(c1,c) << endl;cout << "string 比较:" << compare(c1, d) << endl;return 0;
}
代码说明:
- 一个函数可以包含不同类型的参数,也就可以包含不同模板类型 T;
- 不同参数类型的函数模板,在实参满足函数实现方法的前提下,可以处理相同类型的实参,亦可以处理不同类型的实参;
错误警告:
该函数模板不能判断字符串大小,仅能判断string类,因为字符串比较不能通过“>""<""==”,而是strcmp()函数,不满足函数实现方法,所以得到错误答案。
函数模板实例化:
template<typename T>
int compare(const T& v1, const T& v2)
{if (v1 > v2) return 1;if (v2 > v1) return -1;return 0;
}int a = 10;int b = 20;
cout << compare(a, b) << endl;
//a,b是int,推断 T是intdouble c = 12.4;
double d = 8.6;
cout << compare(c, d) << endl;
//c,d为double,推断T是double
当我们调用函数模板时,模板中空缺的模板参数由实参决定;
当函数调用的实参为int 时,函数模板告诉编译器模板参数T 为int ,编译器则重新以函数模板创建参数为int 的函数,实参为double 时同理。
编译要求:
函数模板的声明和定义需要在同一文件里
实参推断:
当函数模板调用时,如果函数实参无法直接推断出函数的模板类型,则需要自行显式指定
template<typename T>
T Max(T a, T b)
{cout << "T Max(T,T)" << endl;return a > b ? a : b;
}int main()
{//可以直接推断int a = Max(10, 20);//错误,不能通过实参推断出模板实参//int b = Max(200, 'a');return 0;
}
引例:
int c = Max<int>(200,'a');//可以,显式类型转换,可以通过实参推断int d = Max(200,(int)'a');int e =Max((char)200,'a');
函数模板重载:
函数模板重载,区别于参数列表不同;
一个文件里可以存在多个同名普通函数与重载的函数模板,但是普通函数的优先级高于函数模板
获取两个参数的最大值
template<typename A1>
A1 Max(const A1& a, const A1& b)
{cout << "函数模板:" << endl;return (a >= b ? a : b);
}//返回数组最大值:
template<typename B>
B Max(const B* b, int n)
{int i = 0;B max = b[0];while (i < n){if (max < b[i])max = b[i++];elsei++;}cout << "函数模板:" << endl;return max;
}
//返回字符串最大值:
char* Max(char* c1, char* c2)
{cout << "普通函数:" << endl;int i = strcmp(c1, c2);if (i == 1)return c1;else return c2;
}
int Max(int a, int b)
{cout << "普通函数:" << endl;return a > b ? a : b;
}
int main()
{//普通函数char a[] = {"abc"};char b[] = { "bcd" };cout << Max(a, b) << endl;int c = 2, d = 3;cout << Max(c, d) << endl;int t[] = { 1,2,3,4,5 };cout << Max(t, sizeof(t) / sizeof(t[0])) << endl;
}
第二组输出,属于可以匹配普通函数,亦可以匹配函数模板,但是普通函数的优先级高,则选择普通函数。