C++学习笔记24 函数模板

来源:互联网 发布:rss源码 编辑:程序博客网 时间:2024/06/01 09:57

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)92014年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;显示声明返回类型参数即可 


总结:

函数模板可以根据类型实参对函数进行推导调用

函数模板可以显示的指定类型参数

函数模板可以被重载

0 0