1:泛型编程的概念:
―不考虑具体数据类型的编程模式
对于Swap函数可以考虑下面的泛型写法
Swap(T& a,T& b)
{
T t = a;
a = b;
b = t;
}
Swap泛型写法中的 TT 不是一个具体的数据类型,而是泛指任意的数据类型。
C++中泛型编程
―函数模板
―提供一种特殊的函数可用不同类型进行调用
―看起来和普通函数很相似,区别是类型可被参数化
template <typename T>
void Swap(T& a, T& b)
{
T t = a;
a = b;
b = t;
}
函数模板的语法规则
―template关键字用于声明开始进行泛型编程
―typename关键字用于声明泛指类型
函数模板的应用
―自动类型推导调用
―具体类型显示调用
01.#include <iostream>
02.using namespace std;
03.template<typename T> //模板声明,其中T为类型参数
04.T max(T a,T b,T c) //定义一个通用函数,用T作虚拟的类型名
05.{
06. if(b>a) a=b;
07. if(c>a) a=c;
08. return a;
09.}
10.
11.int main( )
12.{
13. int i1=185,i2=-76,i3=567,i;
14. double d1=56.87,d2=90.23,d3=-3214.78,d;
15. long g1=67854,g2=-912456,g3=673456,g;
16. i=max(i1,i2,i3); //调用模板函数,此时T被int取代
17. d=max(d1,d2,d3); //调用模板函数,此时T被double取代
18. g=max(g1,g2,g3); //调用模板函数,此时T被long取代
19. cout<<"i_max="<<i<<endl;
20. cout<<"f_max="<<f<<endl;
21. cout<<"g_max="<<g<<endl;
22. return 0;
23.}
函数模板的深入理解
― 编译器并不是把函数模板处理成能够处理任意类型的函数
― 编译器从函数模板通过具体类型产生不同的函数
― 编译器会对函数模板进行两次编译
―在声明的地方对模板代码本身进行编译
―在调用的地方对参数替换后的代码进行编译
2:函数模板遇上函数重载
函数模板可以像普通函数一样被重载:
C++编译器优先考虑普通函数
如果函数模板可以产生一个更好的匹配,那么选择模板
可以通过空模板实参列表的语法限定编译器只通过模板匹配
#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
template<typename T>
T Max(T a, T b)
{
cout<<"函数模板T Max(T a, T b)"<<endl;
return a>b?a:b;
}
template<typename T>
T Max(T a, T b, T c)
{
cout<<"函数模板T Max(T a, T b,T c)"<<endl;
return Max(Max(a,b),c);
}
int Max(int a , int b)
{
cout<<"普通函数 int Max(int a , int b)"<<endl;
return a>b?a:b;
}
int main(int argc, char** argv) {
int a = 1;
int b = 2;
cout<<Max(a,b)<<endl;//C++编译器优先考虑普通函数
cout<<Max<>(a,b)<<endl;//可以通过空模板实参列表的语法限定编译器只通过模板匹配
float fa = 3;
float fb = 4;
cout<<Max<float>(fa,fb)<<endl;// 如果函数模板可以产生一个更好的匹配,那么选择模板
char ca = 5;
char cb = 9;
char cc = 8;
cout<<(int)Max(ca,cb,cc)<<endl;
/*
普通函数 int Max(int a , int b)
2
函数模板T Max(T a, T b)
2
函数模板T Max(T a, T b)
4
函数模板T Max(T a, T b,T c)
函数模板T Max(T a, T b)
函数模板T Max(T a, T b)
9
2014年9月10日22:37:03
*/
return 0;
}
注意:
函数模板不允许自动类型转化
普通函数能够进行自动类型转换
cout<< Max("a", 23)<<endl;
只能调用普通函数,不能调用函数模板
3:多参数函数模板
函数模板可以定义任意多个不同的类型参数
template<typename T1, typename T2, typename RT>
RT Add(T1 a, T2 b)
{
return static_cast<RT>(a+b);
}
cout<<Add(char,float,double>('a',100)<<endl;
进行自动类型推导吗?
当声明的类型参数为返回值类型时,无法进行自动类型推导。
不完美解决方案:
将返回类型参数声明到第一个参数位置,调
用时只需显示声明返回类型参数即可。
template<typename RT,typename T1, typename T2>
RT Add(T1 a, T2 b)
{
return static_cast<RT>(a+b);
}
cout<<Add<RT>('a',100)<<endl;显示声明返回类型参数即可
总结:
函数模板可以根据类型实参对函数进行推导调用
函数模板可以显示的指定类型参数
函数模板可以被重载