“模板”学习笔记(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行的具体化了的函数模板,从而只是交换两个人的年龄大小,而不是他们的名字。