“模板”学习笔记(4)-----如何解决函数模板的重载问题

=================具体化函数模板的方法====================

      要是我们想要解决《“模板”学习笔记(3)-----为啥函数模板不能重载》讨论的函数模板无法重载的问题,我们必须要利用C++为模板提供的一个特殊的属性,一个具体化函数定义的特性,即显式具体化一个函数模板。比如说,我们将Swap()函数声明成:

void Swap(ElementType &a,ElementType &b)

  这就表示Swap()函数中有两个不具体的参数ElementType &a和ElementType &b,而我们现在要具体化这两个参数,比如说我们要把这两个参数换成people结构体,即把Swap()函数中的参数换成这样: 

people &a,people &b

  这样一来,当我们在程序中想Swap()函数传递关于people结构体的参数时,编译器就会立即找到具体化接受两个people类型的Swap()函数,而不会使用原先定义的模板。这就叫显式具体化一个函数模板,说白了就是在原有函数模板的基础上新增一个接受固定参数的函数。在C++中我们是这样具体化一个函数模板的:

template<>void Swap<people>(people &a,people &b);

  这样一来,在编译的时候,如果我们为Swap()函数传递的参数为people类型的参数,那么编译器就会根据这个模板自动创建下面这个函数:

void Swap(people &a,people &b)

  这样一来,就达到了重载函数模板的问题了。但是有一点需要注意的是,我们在这里如果具体化了关于people的函数模板,那么具体化类型为people的函数模板只可适用于people结构的变量,其他变量还是照样会调用原先定义的Swap()模板函数的。

      下面,我们来用一个例子演示一下这个问题:

#include <iostream>
using namespace std;
struct people
{
	char name[10];
	int age;
};
template<class ElementType>
void Swap(ElementType &a,ElementType &b)
{
	ElementType temp;
	temp=b;
	b=a;
	a=temp;	
}

template<>void Swap<people>(people &a,people &b)
{
	int temp;
	temp=b.age;
	b.age=a.age;
	a.age=temp;
}
int main()
{
	int x=1,y=2;
	cout<<"交换之前,x="<<x<<"\ty="<<y<<endl;
	Swap(x,y);
	cout<<"交换之后,x="<<x<<"\ty="<<y<<endl;
	people person_1={"unqiue",22};
	people person_2={"jack",30};
	cout<<"交换之前,第一个人的名字叫:"<<person_1.name<<"\t年龄为:"<<person_1.age<<endl;
	cout<<"交换之前,第二个人的名字叫:"<<person_2.name<<"\t年龄为:"<<person_2.age<<endl;
	Swap(person_1,person_2);
	cout<<"调用具体化为people的Swap()函数的结果:"<<endl;
	cout<<"交换之后,第一个人的名字叫:"<<person_1.name<<"\t年龄为:"<<person_1.age<<endl;
	cout<<"交换之后,第二个人的名字叫:"<<person_2.name<<"\t年龄为:"<<person_2.age<<endl;
	return 0;
}

  程序的输出如下:

      从输出我们就可以看出,当传递给编译器的Swap()函数的参数为整型变量的时候,它照样会调用位于程序第9行的Swap()函数模板,但是如果传递给Swap()函数的参数为people结构体类型的变量时,编译器却调用了位于程序第17行的具体化了的函数模板,从而只是交换两个人的年龄大小,而不是他们的名字。

posted @ 2011-08-11 11:57  uniqueliu  阅读(1643)  评论(3编辑  收藏  举报