模板的具体化和实例化

什么是模板的具体化和实例化呢?有以下模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
template <typename T>
void Swap(T &a, T &b);

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

int main()
{
using namespace std;
int i = 10;
int j = 20;
Swap(i, j); // 标志1
...
...
}

在上面的模板函数声明中,声明一个交换类型为T的两个元素。代码包含函数模板并不会生产函数定义,它只是一个用于生产函数定义的方案。当编译器使用模板为特定类型生产函数定义时(程序标志1处),得到的是模板实例化,值得注意的是这里实例化的方式为隐式实例化,因为编译器发现你用的int类型参数,所以就隐式实例化。
在C++中,还有一种实例化方式:显式实例化,语法如下:

1
template void Swap<int>(int, int);  //显式实例化

与实例化不太一样的是显式具体化,具体的声明语法如下:

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

显示具体化不同的是:需要专门为int类型显式地定义函数定义,显式具体化声明在关键字template后包含<>,而显式实例化没有。

此时,我们会发现有很多不同的函数定义,那么我们使用某个函数的时候,编译器到底使用的哪个函数原型呢? 编译器选择原型的时候,非模板函数版本 > 显式具体化 > 通用模板版本。

另外一点,同一个类型的显示实例化和显式具体化不能同时使用,会出错。