參考C++ Primer Plus(中文第五版)P246--258關于函數模闆的材料,總結如下:
結合原書中以下代碼分析:
//程式清單8.13
// twoswap.cpp -- specialization overrides a template
#include <iostream>
template <class Any>
void Swap(Any &a, Any &b);
struct job
{
char name[40];
double salary;
int floor;
};
// explicit specialization
template <> void Swap<job>(job &j1, job &j2);
void Show(job &j);
int main()
{
using namespace std;
cout.precision(2);
cout.setf(ios::fixed, ios::floatfield);
int i = 10, j = 20;
cout << "i, j = " << i << ", " << j << ".\n";
cout << "Using compiler-generated int swapper:\n";
Swap(i,j); // generates void Swap(int &, int &)
cout << "Now i, j = " << i << ", " << j << ".\n";
job sue = {"Susan Yaffee", 73000.60, 7};
job sidney = {"Sidney Taffee", 78060.72, 9};
cout << "Before job swapping:\n";
Show(sue);
Show(sidney);
Swap(sue, sidney); // uses void Swap(job &, job &)
cout << "After job swapping:\n";
Show(sue);
Show(sidney);
return 0;
}
template <class Any>
void Swap(Any &a, Any &b) // general version
{
Any temp;
temp = a;
a = b;
b = temp;
}
// swaps just the salary and floor fields of a job structure
template <> void Swap<job>(job &j1, job &j2) // specialization
{
double t1;
int t2;
t1 = j1.salary;
j1.salary = j2.salary;
j2.salary = t1;
t2 = j1.floor;
j1.floor = j2.floor;
j2.floor = t2;
}
void Show(job &j)
{
using namespace std;
cout << j.name << ": $" << j.salary
<< " on floor " << j.floor << endl;
}
觀察可知,在僅有的一個twoswap.cpp檔案中,我們在main函數之前聲明了一個正常模闆函數,即:
template <class Any>
void Swap(Any &a, Any &b)
還聲明了一個顯示具體化的模闆函數:
// explicit specialization
template <> void Swap<job>(job &j1, job &j2);
void Show(job &j);
在main函數之後,接着定義了這兩個函數。
在這裡,有必要講一下,如果我們在同一個檔案中,定義了三個同名的函數,其中一個是正常模闆函數,一個是顯示具體化的模闆函數,一個是正常的非模闆函數。那麼之間如果存在覆寫的話,優先級是怎樣的呢?

書中告訴了我們答案,它說在C++标準中,具體化的模闆函數将覆寫正常模闆函數,而正常的非模闆函數将覆寫具體化的模闆函數和正常模闆函數。
c++标準還規定了具體化的原型和定義都必須是以template<>打頭,通過名稱來指出類型。
帶代碼中包含模闆本身并不會生成函數定義,它隻是一個用于生成函數定義的方案。編譯器使用模闆為特定類型生成函數定義時,得到的是模闆執行個體(instantiation)。模闆并非函數定義,但是使用特定類型的執行個體是函數定義。這種執行個體化方式被稱為隐式執行個體化(implicit instantiation),就是說:編譯器在遇到模闆函數的聲明和定義代碼時,并沒有給出一個實際的執行個體定義,它隻是獲得了關于一個模闆函數的介紹,而在遇到調用特定類型的模闆函數執行個體時,編譯器才決定以特定類型代替模闆函數的模闆類型參數,并給出特定類型的執行個體化定義。哪照這樣說,如果我們不調用特定類型的模闆函數,模闆也就不會執行個體化了。
但是,現在我們也可以是一個模闆函數顯示執行個體化(explicit instantiation),就是說我們可以直接指令編譯器建立特定的執行個體,方式為:
template <> void 函數名<特定類型>(特定類型參數清單)
如:
template void Swap<job>(job &j1, job &j2)
這裡注意,顯示執行個體化和顯示具體化的意思是不一樣的!!!差別在于:
1.顯示具體化(explicit specialization)是針對某種特定類型,需要使用與模闆函數定義中不同的特定算法時,需要對模闆顯示具體化,格式例子如下:
template <> void Swap<job>(job &j1, job &j2) // explicit specialization 顯示具體化
2.顯示執行個體化(explicit instantiation)是實作模闆函數定義的執行個體,格式例子如下:
template void Swap<job>(job &j1, job &j2) // explicit instantiation 顯示執行個體化
注意顯示具體化的聲明和定義中代碼,在template後面都有一個尖括号<>,而顯示執行個體化都沒有。
實際上,如果對同一個模闆函數的