现在的位置: 首页 > 综合 > 正文

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

2016年02月04日 ⁄ 综合 ⁄ 共 2243字 ⁄ 字号 评论关闭

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

总结:

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

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

函数模板可以被重载

抱歉!评论已关闭.