您的位置:首页 > 编程语言 > C语言/C++

C++ 函数模板

2017-03-30 10:55 148 查看
一,函数模板

函数模板是通用的函数描述,如果需要将同一种算法用于不同类型的函数,可以使用模板。

函数模板定义

#include <iostream>
using namespace std;

template <typename Type>
void Swap(Type &a, Type &b){
Type temp = a;
a = b;
b = temp;
}

int main(){
int a = 10, b= 20;
Swap(a, b);
cout<<"a: "<<a<<endl;
cout<<"b: "<<b<<endl;
return 0;
}


输出结果

a: 20
b: 10

Process returned 0 (0x0)   execution time : 0.007 s
Press any key to continue.


二,重载函数模板

可以像重载常规函数定义那样重载函数模板定义,和常规重载一样,被重载的模板的函数特征标必须不同

template <typename Type>
void Swap(Type &a, Type &b){
Type temp = a;
a = b;
b = temp;
}

template <typename Type>
void Swap(Type *a, Type *b, int n){
Type temp;
for(int i = 0; i < n; i ++){
temp = a[i];
a[i] = b[i];
b[i] = temp;
}
}


三,具体化

在代码中包含模板本身并不会生成函数定义,它只是一个用于生成函数定义的方案。隐式实例化,显示实例化和显示具体化统称为具体化。

实例:

template <typename Type>
void Swap(Type &a, Type &b){
Type temp = a;
a = b;
b = temp;
}


1, 隐式实例化

函数调用Swap(a, b)导致编译器生成Swap()的一个实例,该实例使用int型。模板并非函数定义,但是使用int的模板实例是函数定义,这种实例化方式成为隐式实例化。编译器之所以知道要进行函数定义,是由于程序调用Swap()函数时提供了int参数。

2,显示实例化

最初编译器只能通过隐式实例化,来生成模板函数的定义,但是现在C++还允许显示实例化,这意味着可以直接命令编译器创建特定的实例。其语法是,声明所需的类型--使用<>符号指示类型,并在声明的前面加上template关键字。如下:template  void  Swap<int>(int, int)。

3,显示具体化

struct Student{
string name;
int age;
};


在程序中定义了上面的结构体,可以使用前面提供的Swap函数来交换两个结构体的内容。然而假如我们只想交换name成员变量,而不交换age成员变量则需要使用不同的代码,但是Swap的参数将保持不变,因此无法使用模板重载来提供其他的代码。可以提供一个具体化函数定义--成为显示具体化,其中包含所需的代码。当编译器找到与函数调用匹配的具体化定义时,将使用该定义,而不再寻找模板。具体化机制随着C++的演变而不断发生变化,下面介绍C++标准定义的形式:

a,对于给定的函数名,可以有非模板函数、模板函数与显示具体化模板函数以及他们的重载的版本。

b,显示具体化的原型和定义应以template<>开头,并通过名称来指定类型。

c,具体化优先与常规模板,而非模板函数优于具体化与常规模板。

#include <iostream>
using namespace std;

struct Student{
string name;
int age;
Student(string name, int age):name(name),age(age){}
};

template <typename Type> void Swap(Type &a, Type &b){ Type temp = a; a = b; b = temp; }

template <> void Swap<Student>(Student &a, Student &b){
string name = a.name;
a.name = b.name;
b.name = name;
}

int main(){
Student a("zhangsan", 20);
Student b("lisi", 25);
Swap(a, b);
cout<<"a.name: "<<a.name<<endl;
cout<<"b.name: "<<b.name<<endl;
return 0;
}
输出结果

a.name: lisi
b.name: zhangsan

Process returned 0 (0x0)   execution time : 0.007 s
Press any key to continue.


四,实例化与具体化的区别

1,实例化

实例化语法,声明所需的类型--用<>符号指示类型,并在声明前面加上关键字template。

template  void  Swap(int, int);

上面声明的意思是,使用Swap模板生成int类型的函数定义。

2,显示具体化

与上面实例化不同的是,显示具体化使用下面两个等价的声明之一:

template  <>  void  Swap<int>(int, int);

template  <>  void  Swap(int, int);

与上面实例化的区别是,上面这些声明的意思是,不要使用Swap模板来生成函数定义,而是用专门为int类型显示定义的函数定义。这些原型必须有自己的函数定义。显示具体化声明在关键字template后面包含<>,而显示实例化没有。

注意:

试图在同一个文件中使用同一种类型的显示实例和显示具体化将出错。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: