模板代碼和非模板代碼是有區別的,如果像非模板代碼那樣把模板的聲明放在頭文件.h中,把模板的定義放在源文件.cpp中,那麼使用這個模板時會得到一個鏈接錯誤。這個錯誤的原因在於,模板的定義還沒有被實例化。為了實例化一個模板,編譯器必須知道哪一個定義應該被實例化以及使用什麼樣的模板參數來實例化。
我們可以用以下三種方式來組織模板代碼:
1. 包含模型(Inclusion Modal)
a. 把模板的定義包含進聲明模板的頭文件中,如果模板聲明在頭文件tmpl.h中,定義在tmpl.cpp中,那可以將#include "tmpl.cpp"添加到tmpl.h文件的末尾。
b. 或者在每一個使用模板的C++文件中包含tmpl.cpp文件來達到目的。
c. 當然也可以不用.cpp文件,把模板聲明和定義放在同一個.h文件裡。
包含模型能夠確保所有需要的模板都已經實例化,這是因為:當需要進行實例化的時候,C++編譯系統會自動產生所對應的實例化體。
2. 顯示實例化(Explicit Instantiation)
顯式實例化由關鍵字template和緊接其後的我們所需要實例化的實體(可以是類、函數、類成員函數等)的聲明組成,而且該聲明是一個已經用實參完全替換參數之後的聲明。
a. template const int& max(const int& a, const int& b); // 函數模板的顯式實例化
b. template class Array<char>; // 類模板的顯式實例化
c. template unsigned int Array<char>::GetSize(); // 類模板成員函數的顯式實例化
3. 分離模型(Separation Modal)
C++標准還給出了另一種機制來組織模板代碼:導出模板(exporting template),這種機制通常也被稱為C++模板的分離模型。
分離模型只需在模板聲明的.h文件裡加export關鍵字,如:
export template <typename T> void func(const T&);
然而VC++編譯器到目前為止並不支持分離模型。