欧莱雅男士发蜡:“模板”学习笔记(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 &a,people &b);
这样一来,在编译的时候,如果我们为Swap()函数传递的参数为people类型的参数,那么编译器就会根据这个模板自动创建下面这个函数:
void
Swap(people &a,people &b)
这样一来,就达到了重载函数模板的问题了。但是有一点需要注意的是,我们在这里如果具体化了关于people的函数模板,那么具体化类型为people的函数模板只可适用于people结构的变量,其他变量还是照样会调用原先定义的Swap()模板函数的。
下面,我们来用一个例子演示一下这个问题:
123456789101112131415161718192021222324252627282930313233343536373839#include
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 &a,people &b)
{
int
temp;
temp=b.age;
b.age=a.age;
a.age=temp;
}
int
main()
{
int
x=1,y=2;
cout<<
"交换之前,x="
<"\ty="
<
Swap(x,y);
cout<<
"交换之后,x="
<"\ty="
<
people person_1={
"unqiue"
,22};
people person_2={
"jack"
,30};
cout<<
"交换之前,第一个人的名字叫:"
<"\t年龄为:"
<
cout<<
"交换之前,第二个人的名字叫:"
<"\t年龄为:"
<
Swap(person_1,person_2);
cout<<
"调用具体化为people的Swap()函数的结果:"
<
cout<<
"交换之后,第一个人的名字叫:"
<"\t年龄为:"
<
cout<<
"交换之后,第二个人的名字叫:"
<"\t年龄为:"
<
return
0;
}
程序的输出如下:
从输出我们就可以看出,当传递给编译器的Swap()函数的参数为整型变量的时候,它照样会调用位于程序第9行的Swap()函数模板,但是如果传递给Swap()函数的参数为people结构体类型的变量时,编译器却调用了位于程序第17行的具体化了的函数模板,从而只是交换两个人的年龄大小,而不是他们的名字。