函数模板
模板把函数或类要处理的数据类型参数化,表现为参数的多态性,成为类属;
模板用于表达逻辑结构相同,但是具体数据元素不同的数据对象的通用行为;
函数模板
模板说明
重载函数使编程变得方便,因为对于执行类似操作的一组函数,只要记住一个函数名称即可。但是,每个函数都必须单独编写。
声明
函数模板定义由模板说明和函数定义组成;
模板说明的类属参数必须在函数定义中至少出现一次;
函数参数表中可以使用类属类型参数,也可以使用一般类型参数;
#include <iostream>
using namespace std;
template <typename T>
void myswap(T &a, T &b) //让数据类型参数化
{
T t = a;
a = b;
b = t;
}
//逻辑一样,处理的数据类型一样
void intswap(int &a, int &b)
{
int c = a;
a = b;
b = c;
}
void charswap(char &a, char &b)
{
char c = a;
a = b;
b = c;
}
int main1(void)
{
int a = 1;
int b = 2;
char c = 'A';
char d = 'B';
intswap(a, b);
charswap(c, d);
printf("a = %d b = %d\n", a, b);
printf("c = %c d = %c\n", c, d);
system("pause");
return 0;
}
int main()
{
int x = 1;
int y = 2;
char c1 = 'A';
char c2 = 'B';
myswap(x, y); //自动类型推导
myswap<int>(x, y); //具体类型调用
myswap(c1, c2);
//myswap<char>(c1, c2);
printf("x = %d y = %d\n", x, y);
printf("c1 = %c c2 = %c\n", c1, c2);
system("pause");
}
加强
#include <iostream>
using namespace std;
/*
int printArray(int *p, int num)
{
int i, j;
for (i = 0; i < num; i++)
{
cout << p[i] << endl;
}
return 0;
}
*/
template <typename T>
int printArray(T *p, T num)
{
T i, j;
for (i = 0; i < num; i++)
{
cout << p[i] << endl;
}
return 0;
}
template <typename T1, typename T2>
int sortArray(T1 *p, T2 num)
{
T1 i, j, temp;
for (i = 0; i < num; i++)
{
for (j = i + 1; j < num; j++)
{
if (p[i] > p[j])
{
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
return 0;
}
void main()
{
/*
int i[] = { 1, 3, 4, 56, 7, 134, 2, 534, 4, 3 };
int num = sizeof(i) / sizeof(int);
printArray<int>(i, num);
sortArray<int>(i, num);
printArray<int>(i, num);
char buf[] = "dasdfsagassdasgsadsadfasdal";
int len = strlen(buf);
printArray<char>(buf, len);
sortArray<char>(buf, len);
printArray<char>(buf, len);
*/
char buf[] = "dasdfsagassdasgsadsadfasdal";
int len = strlen(buf);
printArray<char>(buf, len);
sortArray<char,int>(buf, len);
printArray<char>(buf, len);
system("pause");
}
模板函数重载
#include <iostream>
using namespace std;
template<typename T>
void myswap(T &a,T &b)
{
T c;
c = a;
a = b;
b = c;
}
void myswap(int &a, char &b)
{
printf("函数重载");
}
//函数模板严格的检查类型
int main()
{
int a = 10;
char b = 'A';
myswap(a, b);
system("pause");
return 0;
}
- 寻找和使用最符合函数名和函数类型的函数,若找到则调用
- 否则,寻找一个函数模板,将其实例化产生一个匹配的函数模板,若找到则调用它;
- 否则,寻找可以通过类型转换进行参数匹配的函数重载
- 如果上述均找不到匹配函数,则错误
C++优先选择普通函数
深入
- 编译器并不是把函数模板处理成能够处理任意类型的函数
- 编译器从函数模板通过具体类型产生不同的函数
- 在声明的地方对函数模板的代码进行编译
- 在调用的地方对参数替换后的代码进行编译