template <class T>
template <class T, class U>
template <class T, int N>
template <class T = char>
template <int Tfunc (int)>
從編譯器的角度來(lái)看,模板不同于一般的函數(shù)或類。
它們?cè)谛枰獣r(shí)才被編譯(compiled on demand),
也就是說一個(gè)模板的代碼直到需要生成一個(gè)對(duì)象的時(shí)候(instantiation)才被編譯。
當(dāng)需要instantiation的時(shí)候,編譯器根據(jù)模板為特定的調(diào)用數(shù)據(jù)類型生成一個(gè)特殊的函數(shù)。
當(dāng)工程變得越來(lái)越大的時(shí)候,程序代碼通常會(huì)被分割為多個(gè)源程序文件。
在這種情況下,通常接口(interface)和實(shí)現(xiàn)(implementation)是分開的。
用一個(gè)函數(shù)庫(kù)做例子
接口通常包括所有能被調(diào)用的函數(shù)的原型定義。
它們通常被定義在以.h 為擴(kuò)展名的頭文件 (header file) 中;
而實(shí)現(xiàn) (函數(shù)的定義)
則在獨(dú)立的C++代碼文件中。
模板這種類似宏(macro-like) 的功能,對(duì)多文件工程有一定的限制:
函數(shù)或類模板的實(shí)現(xiàn) (定義) 必須與原型聲明在同一個(gè)文件中。
也就是說我們不能再 將接口(interface)存儲(chǔ)在單獨(dú)的頭文件中,
而必須將接口和實(shí)現(xiàn)放在使用模板的同一個(gè)文件中。
回到函數(shù)庫(kù)的例子,如果我們想要建立一個(gè)函數(shù)模板的庫(kù),我們不能再使用頭文件(.h) ,取而代之,我們應(yīng)該生成一個(gè)模板文件(template file),將函數(shù)模板的接口和實(shí)現(xiàn) 都放在這個(gè)文件中 (這種文件沒有慣用擴(kuò)展名,除了不要使用.h擴(kuò)展名或不要不加任何擴(kuò)展名)。
在一個(gè)工程中多次包含同時(shí)具有聲明和實(shí)現(xiàn)的模板文件并不會(huì)產(chǎn)生鏈接錯(cuò)誤 (linkage errors),因?yàn)樗鼈冎挥性谛枰獣r(shí)才被編譯,而兼容模板的編譯器應(yīng)該已經(jīng)考慮到這種情況,不會(huì)生成重復(fù)的代碼。