參考:http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file
在 C++ 中定義普通的類的時候,比較清晰和普遍的做法是在 .h 文件中聲明類的接口,如果有 inline 函數(shù)也一并放在 .h 中的 class 關(guān)鍵字中。然后在 .cpp 文件中實現(xiàn) .h 中聲明的接口。
在定義模板類時,如果要將接口與實現(xiàn)分離會略有不同。如果把模板類的實現(xiàn)像普通類一樣放在 .cpp 文件中鏈接器會報錯。
有兩個方法可以實現(xiàn)模板類的接口和實現(xiàn)在文件中的分離:
一個前提
“類模板的成員函數(shù)是一個普通函數(shù)。但是類模板的每個實例都有其自己版本的成員函數(shù)。因此類模板的成員函數(shù)具有和模板相同的模板參數(shù)。因此定義在類模板之外的成員函數(shù)就必須以關(guān)鍵字 template 開始,后接類模板參數(shù)列表?!?br> ——《C++ Primer》中文版,第五版,P585
使用 .tpp 文件實現(xiàn)類模板的接口與實現(xiàn)的文件分離
比如說有這樣一個模板類,這是它的接口:
template <typename Node>
class TestTemplate{
public:
TestTemplate(Node node):
data(node) { }
Node data;
void print();
};
這是它的實現(xiàn):
template <typename node>
void TestTemplate<node>::print(){
std::cout << "TestTemplate " << data << std::endl;
}
如果把它們分別放在 .h 和 .cpp 文件中,鏈接器會報錯,提示找不到實現(xiàn)。
在 .h 文件中模板類的實現(xiàn)下加這一句:
#include "TestTemplate.tpp"
然后把實現(xiàn)放在名為 TestTemplate.tpp 文件中,即可。
使用顯式聲明實現(xiàn)類模板的接口與實現(xiàn)的文件分離
假設(shè)上面那個類的接口與實現(xiàn)分別放在了 .h 和 .cpp 文件中。然后在 .cpp 文件中顯式的聲明要使用的模板類實例,比如:
template class TestTemplate<int>;
然后,使用 TestTemplate<int> 也可以通過編譯鏈接,但是只能使用已經(jīng)顯式聲明的模板類實例。比如如果還要使用 TestTemplate<float>,就要這樣:
template class TestTemplate<int>;
template class TestTemplate<float>;
就是說只能只用已經(jīng)顯式聲明過的模板類實例。