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

c++复习之 函数模板template(10)

2018-03-05 15:20 399 查看

函数模板template

函数模板是通用的函数描述,它们使用泛型来定义函数,其中的泛型可用具体的类型(如int和double)替换。通过将类型作为参数传递给模板,可使编译器生成该类型的函数。这种编程方式也叫做通用编程。由于类型是用参数表示的,因此模板特性有时也被称为参数化类型。

参数模板允许以任意类型的方式来定义函数。例如,可以这样建立一个交换模板:

template<typename Anytype>//或者 template<class Anytype>
void Swap(Anytype &a, Anytype &b)
{
Anytype temp;
temp = a;
a = b;
b = temp;
}


第一行指出,要建立一个模板,并将类型命名为Anytype。关键字template和typename是必需的,除非可以使用关键字class替代typename。例外,必须使用尖括号<>。类型名可以任意选择(T?)。模板不创建任何函数,只是告诉编译器如何定义函数。需要交换int的函数时,编译器将按模板模式创建这样的函数,并用int代替Anytype。

使用模板函数时,在文件的开始位置提供模板函数的原型,并在main()后面提供模板函数的定义。

#include <iostream>
template<typename T>
void Swap(T &a, T &b);

int main()
{
using namespace std;
int i = 10;
int j = 20;
Swap(i, j);

double x = 12.2;
double y = 34.6;
Swap(x, y);

getchar();
return 0;
}

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


运行上述程序后,编译器最终将生成两个独立的函数定义(即不是内联的,和普通函数的声明定义相同),就像手工定义了这些函数一样,最终的代码不包括任何模板,只包含了为程序生成的实际函数。

1 重载的模板

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

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

template <typename T>
void Swap(T *a, T *b, int n);//模板的函数特征标所有不同,在结构上不同才可以


并非所有的模板参数都必须是模板参数类型,int n就不是模板参数类型。

2 模板的局限性

编写的模板可能无法处理某些类型。

3 显式具体化

C++98有如下的方法:

对于给定的函数名,可以有非模板函数、模板函数和显式具体化模板函数以及它们的重载版本。

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

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

“` c++

//non template function prototypr

void Swap(job &, job &);

//template prototype

template

void Swap(T &a, T &b);

//explicit specialization for the job type

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

4 实例化和具体化

在代码中包含函数模板本身并不会生成函数定义,它只是一个用于生成函数定义的方案。编译器使用模板为特定类型生成函数定义时,得到的是模板实例(instantiation)。模板并非函数定义,但使用int的模板实例是函数定义。这种实例化方式被称为隐式实例化(implicit instantiation)。

c++允许显式实例化,直接命令编译器创建特定的实例。

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


隐式实例化、显式实例化和显式具体化统称为具体化(specialization),相同之处在于都是使用具体类型的函数定义,而不是通用描述。

5 编译器选择使用哪个函数版本

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  函数模板