在正常狀況下,c++模板是不容許在頭文件聲明,在cpp文件中實現。那是由於在cpp文件在編譯時內存必需要給它分配儲存空間。可是模板自己是一種泛型,在沒有明肯定義聲明類型前,編譯器也沒法知道它的大小。因此就會出現連接失敗。ios
//print.h #ifndef _PRINT_ #define _PRINT_ template<typename T> void print(T obj); #endif
//print.cpp #include "print.h" #include <iostream> using namespace std; template<typename T> void print(T obj) { cout<<obj; }
//main.cpp #include"print.h" int main() { print(100); while(1); return 0; }
若是這樣子編譯的話,就會提示:c++
1>LINK : E:\mycode\模板\Debug\模板分離.exe not found or not built by the last incremental link; performing full link 1>main.obj : error LNK2019: unresolved external symbol "void __cdecl print<int>(int)" (??$print@H@@YAXH@Z) referenced in function _main 1>E:\mycode\模板\Debug\模板分離.exe : fatal error LNK1120: 1 unresolved externals
經常使用的解決方法一共有2種:函數
1是將定義也在頭文件中,這種就不用說了。因爲不在cpp文件中定義編譯器也沒有必要一開始分配內存,也就不會報錯。ui
2採用顯式的實例化聲明,剛纔我說過,定義在cpp文件中的模板函數因爲沒有肯定的類型,致使編譯器沒法分配內存。這時候只要給以肯定的類型,也就是顯式的實例化聲明就能夠了,只須要在頭文件中用肯定的類型再聲明一次便可。spa
//print.h #ifndef _PRINT_ #define _PRINT_ template<typename T> void print(T obj); template void print<int>(int); #endif
這樣在編譯就能經過了。code