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;显示声明返回类型参数即可
总结:
函数模板可以根据类型实参对函数进行推导调用
函数模板可以显示的指定类型参数
函数模板可以被重载