模板函式的定義和宣告須在同一檔案內

2021-06-02 08:54:26 字數 1036 閱讀 7733

按照c++中**的慣例,類宣告在h檔案中,類定義在cpp檔案中,相應的成員函式宣告也在h檔案中,定義在cpp檔案中。但是如果這樣的架構用在模板函式中,在呼叫模板函式的地方鏈結器便會報錯,error lnk2001: unresolved external symbol。將定義寫在與宣告相同的檔案中問題解決,解釋如下:

「大部分編譯器在編譯模板時都使用包含模式。也就是一般使用的把模板放到標頭檔案中再包含。

當你不使用這個模版函式或模版類,編譯器並不例項化它。當你使用時,編譯器需要例項化它。因為編譯器是一次只能處理乙個編譯單元,也就是一次處理乙個cpp檔案,所以例項化時需要看到該模板的完整定義,所以都放在標頭檔案中。

這不同於普通的函式,在使用普通的函式時,編譯時只需看到該函式的宣告即可編譯,而在鏈結時由鏈結器來確定該函式的實體。」

"temp.h:

void fun(t);

temp.cpp:

#include "temp.h"

void fun(t){}

main.cpp:

#include "temp.h"

void main()

由於main.cpp用到了fun(a),所以在編譯main.cpp的時候,編譯器知道它要用int來例項化fun(t)中的t,也就是要例項化fun(int),而要例項化乙個函式模板就必須要知道這個函式模板的定義,但是由於main.cpp和包含函式模板定義的temp.cpp是分開編譯的,所以編譯器在編譯main.cpp的時候就不能夠用int來例項化fun(t),這樣編譯器就只能夠把fun(a)當成乙個外部符號,交由linker來resolve。

另外編譯器在編譯temp.cpp的時候,同樣因為temp.cpp和main.cpp是分開編譯的,所以此時編譯器並不知道main.cpp中用到了fun(a),所以此時編譯器雖然知道函式模板的定義,但也不會去例項化任何fun,當然就不會用int來例項化fun了。

結果就是,你在main.obj引用了外部符號fun,但是在temp.obj中不存在fun,所以linker就會報告無法解析的外部符號了。"

這裡引用了xzgyb和john titor對該問題的解釋。

模板函式的定義和宣告須在同一檔案內

按照c 中 的慣例,類宣告在h檔案中,類定義在cpp檔案中,相應的成員函式宣告也在h檔案中,定義在cpp檔案中。但是如果這樣的架構用在模板函式中,在呼叫模板函式的地方鏈結器便會報錯,error lnk2001 unresolved external symbol。將定義寫在與宣告相同的檔案中問題解決...

模板宣告與定義要放在同一檔案中?

通常情況下,你會在.h檔案中宣告函式和類,而將它們的定義放置在乙個單獨的.cpp檔案中。但是在使用模板時,這種習慣性做法將變得不再有用,因為當例項化乙個模板時,編譯器必須看到模板確切的定義,而不僅僅是它的宣告。因此,最好的辦法就是將模板的宣告和定義都放置在同乙個.h檔案中。這就是為什麼所有的stl標...

模板宣告與定義要放在同一檔案中?

通常情況下,你會在.h檔案中宣告函式和類,而將它們的定義放置在乙個單獨的.cpp檔案中。但是在使用模板時,這種習慣性做法將變得不再有用,因為當例項化乙個模板時,編譯器必須看到模板確切的定義,而不僅僅是它的宣告。因此,最好的辦法就是將模板的宣告和定義都放置在同乙個.h檔案中。這就是為什麼所有的stl標...