函数模板的形式:
template <typename AnyType>
void swap1(AnyType& a, AnyType& b) {;}
编写代码时,若只是参数类型发生改变,核心算法并没有变,此时便能使用模板来自动生成其他类型参量的函数。以下例子给出一个swap模板函数,通过该模板函数在程序内部自动生成swap(char&,char&),及swap(int&,int&),注:模板并不创建任何函数,它只是告诉编译器如何定义函数。
#include <iostream>
#include <string>
using namespace std;
// 模板函数申明
template <typename T>
void swap1(T& a, T& b);
int main()
{
char c = 'c';
char b = 'b';
cout << "为交换之前:\n";
cout << "c = " << c << ",b = " << b << endl;
swap1(c, b);
cout << "交换之后:\n";
cout << "c = " << c << ",b = " << b << endl;
int a = 10;
int d = 20;
cout << "为交换之前:\n";
cout << "a = " << a << ",d = " << d << endl;
swap1(a, d);
cout << "交换之后:\n";
cout << "a = " << a << ",d = " << d << endl;
}
// 模板函数定义
template <typename T>
void swap1(T& a, T& b)
{
// 存放临时变量
T temp = a;
a = b;
b = temp;
}
在申明模板函数时template 和 typename 是必须的,或者将typename换成class 也是可以的。
程序运行结果:
重载函数模板
可以像重载常规函数一样重载模板,被重载的模板特征标必须不同,如下例程序清单,原函数模板为swap1(T& a, T& b),而新函数模板特征标为(T[],T[],int)。注意第三个参数为int类型而不是泛型,并不是所有模板参数都必须是泛型。
#include <iostream>
#include <string>
using namespace std;
// 模板函数申明
template <typename T>
void swap1(T& a, T& b);
// 模板函数重载
template <typename T>
void swap1(T* a, T* b,int n);
template <typename T>
void showArray(T* a,int n);
int main()
{
char c = 'c';
char b = 'b';
cout << "为交换之前:\n";
cout << "c = " << c << ",b = " << b << endl;
swap1(c, b);
cout << "交换之后:\n";
cout << "c = " << c << ",b = " << b << endl;
int a = 10;
int d = 20;
cout << "为交换之前:\n";
cout << "a = " << a << ",d = " << d << endl;
swap1(a, d);
cout << "交换之后:\n";
cout << "a = " << a << ",d = " << d << endl;
cout << endl << "函数重载的二次数组\n";
int m[9] = { 1,1,1,2,2,2,3,3,3 };
int n[9] = { 3,3,3,2,2,2,1,1,1 };
cout << "交换之前的m数组:";
showArray(m, 9);
cout << "交换之前的n数组:";
showArray(n, 9);
swap1(m, n, 9);
cout << "交换之后的m数组:";
showArray(m, 9);
cout << "交换之后的n数组:";
showArray(n, 9);
}
// 模板函数定义
template <typename T>
void swap1(T& a, T& b)
{
// 存放临时变量
T temp = a;
a = b;
b = temp;
}
// 函数模板的重载
template <typename T>
void swap1(T* a, T* b,int n)
{
// 创建临时变量
T temp;
for (int i = 0; i < n; i++)
{
temp = a[i];
a[i] = b[i];
b[i] = temp;
}
}
template <typename T>
void showArray(T* a, int n)
{
for (int i = 0; i < n; i++)
{
cout << a[i] << ",";
}
cout << endl;
}
程序运行结果:
显示具体化:
假定job结构如下所示:
struct job
{
char name[40];
double salary;
int floor;
};
结构之间的赋值转换可以通过上面的swap1(T&,T&)进行转换,但有时候我们并不需要结构内部的所有信息都进行交换。如job,我们指定salary和 floor 需要交换,但name 不需要交换 。故不能简单的通过上述模板进行交换,此时便需要使用模板具体化。
注意函数的调用优先级:非模板函数 > 模板具体化 > 模板函数
具体化的形式:template <> void swap1(job& a, job& b)
#include <iostream>
#include <string>
using namespace std;
struct job
{
char name[40];
double salary;
int floor;
};
// 模板函数申明
template <typename T>
void swap1(T& a, T& b);
// 创建模板具体化
template <> void swap1(job& a, job& b);
template <typename T>
void showArray(T* a,int n);
// 创建结构
void showJob(const job&);
int main()
{
job ct{"chentao",100000,10};
job ty{ "tanyue",200000,20 };
char c = 'c';
char b = 'b';
cout << "为交换之前:\n";
cout << "c = " << c << ",b = " << b << endl;
swap1(c, b);
cout << "交换之后:\n";
cout << "c = " << c << ",b = " << b << endl;
cout << "job交换前\n";
cout << "ct :";
showJob(ct);
cout << "ty :";
showJob(ty);
swap1(ct,ty);
cout << "job交换后\n";
cout << "ct :";
showJob(ct);
cout << "ty :";
showJob(ty);
}
// 模板函数定义
template <typename T>
void swap1(T& a, T& b)
{
// 存放临时变量
T temp = a;
a = b;
b = temp;
}
template <typename T>
void showArray(T* a, int n)
{
for (int i = 0; i < n; i++)
{
cout << a[i] << ",";
}
cout << endl;
}
// 模板具体化
template <>
void swap1(job& a, job& b)
{
job temp = a;
a.floor = b.floor;
a.salary = b.salary;
b.floor = temp.floor;
b.salary = temp.salary;
}
void showJob(const job& a)
{
cout << "name = " << a.name << ",floor = " << a.floor << ",salary = " << a.salary << endl;
}
运行结果:
显示实例化
模板函数实例化,如下面代码所示
template<typename T>
T add(const T& a,const T& b)
{
return a+b;
}
.....
.....
.....
int x = 10 ;
double a = 10.2;
cout << add<double>(x,a) << endl ;
其中add<double>(x,a)便为模板函数实例化,它直接使用模板函数创建一个add(const double&, const double&)的函数实例。同时也可以提前申明实例化函数,如下述代码所示:
template void swap<char>(char&,char&);