c++函数模板

C++为什么要引入函数模板呢?

举个例子说明一下:

int swap(int a,int b)

{

int t =a;a=b;b=t;

}

float swap (float a,float b)

{

float t =a;a=b;b=t;

}

double swap(double a,double b)

{

double  t =a;a=b;b=t;

}

char swap (char a,char b)

{

char t =a;a=b;b=t;

}

上面定义了四个重载函数swap,观察四个重载函数,发现除了类型不同,四个函数的函数体的写法完全一样。考虑,将四个函数的类型使用T代替,则上面四个函数的写法就完全一致了:

T swap(T a,T b)

{

T  t =a;a=b;b=t;

}

观察变化:四个重载函数变成了同一个函数写法。

C++中提供了语法来描述上面的函数——函数模板。

下面C++函数模板定义:

template <class 模板类型参数1,class 模板类型参数2 ,…>

返回值类型 函数模板名(模板参数表)

{

函数模板体

}

要求:定义中的所有的模板类型参数必须出现在函数模板的模板参数表中,否则编译将会报错。

上面的四个交换重载函数可以使用函数模板来描述:

template <class  T>

    void  swap(T  a, T b)

{T  t=a;a=b;b=t;

}

有了上面函数模板swap定义,则前面的swap重载函数可以不需要定义了!

例子:

template <calss  T1,class T2>

void f(int a,T1  b)//这个模板定义将出错,因为类型参数T2没有出现在模板参数表                                           //中

{...

}

函数模板定义了一簇函数,因此函数模板不是函数,但可以通过对函数模板进行实例化生成具体的函数,用函数模板实例化生成的具体函数称为模板函数。

如何对函数模板进行实例化?

函数模板的实例化采取隐式实例化方式,也即不需要程序员去实现,在编译阶段由编译器完成实例化并且生成相应的模板函数。

实例化函数模板的调用语法与普通函数的调用是一致的:

  函数模板名(实际参数表);

以上函数模板调用语句编译器的解释:

(1)首先检查是否有类型参数个数完全一致的函数定义,如果有,则使用该函数的函数体进行调用,否则进入(2)

(2)检查通过类型隐式转换后是否存在(1)的情况,如果有,则隐式转换后选择 (1)的方式进行调用,否则进入(3)

(3)检查是否存在函数模板,如果有则生成实际参数类型的对应模板函数再进行调用,否则检查通过类型隐式转换后是否存在函数模板,如果有,则生成相应的模板函数,否则调用失败。

简单例子:

定义函数模板swap:

template <class  T>

    void  swap(T  a, T b)

{T  t=a;a=b;b=t;

}

swap(100,200);//编译器生成模板函数swap(int ,int),并调用

swap(100,‘a’);//编译器将char类型参数隐式转换为int,编译器生成模板函数 //swap(int ,int),并调用

swap(100.4,300)//编译器将int类型参数隐式转换为double,编译器生成模板函 //数 swap(double,double),并调用

应用举例:

请写一个函数模板Sort(T *a,int n)对数组a中n个元素进行排序

函数模板Sort代码:

#include"iostream"
#include"algorithm"
using namespace std;
template<class T1,class T2>
void Sort(T1 *a,T2 num)
{
	T1 temp;
  for(int i=0;i<num-1;i++)
  {
  	for(int j=i+1;j<num;j++)
  	{
  		if(a[j]>a[i])
  		{
  		 temp=a[i];
		 a[i]=a[j];
		 a[j]=temp;	
  		}
  	}
  }
} 
template <class T1,class T2>
void Print(T1 *a,T2 num)
{
	for(int i=0;i<num;i++)
	 cout<<a[i]<<ends;
}
int main()
{
    int *pi;
	char *pj;
	double *pk;
	int num;
	cout<<"请输入数据个数:"<<endl;
	cin>>num;
	pi=new int[num];
	pj=new char[num];
	pk=new double[num];
	cout<<"请输入第一组整型数据:"<<endl; 
	for(int i=0;i<num;i++)
	 {
	 	cin>>pi[i];
	 } 
	 cout<<"请输入第二组字符型数据:"<<endl;
	 for(int i=0;i<num;i++)
	 {
	 	cin>>pj[i];
	 } 
	 cout<<"请输入第三组双精度数据:"<<endl;
	 for(int i=0;i<num;i++)
	 {
	 	cin>>pk[i];
	 } 
	 cout<<endl<<"排序前数据:";
	 Print(pi,num);
	 cout<<endl<<"排序后数据:";
	 Sort(pi,num);
	 Print(pi,num);
	 
	 cout<<endl<<endl<<"排序前数据:";
	 Print(pj,num);
	 cout<<endl<<"排序后数据:";
	 Sort(pj,num);
	 Print(pj,num);
	  
	 cout<<endl<<endl<<"排序前数据:";
	 Print(pk,num);
	 cout<<endl<<"排序后数据:";
	 Sort(pk,num); 
	 Print(pk,num);
	 
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值