C 踩坑 模板類

2021-08-22 14:45:21 字數 1076 閱讀 2338

**

在學習資料結構c++實現的時候,踩中了c++的乙個坑,如下:

/**/

template class search

int bisearch()

return -1;

}private:

st tar;

k key;

};

模板類search的成員函式只能定義在.h檔案中,無法在.cpp檔案中定義,定義則會報錯:

error lnk2019: 無法解析的外部符號 "public: int __thiscall search::bisearch(void)" (?bisearch@?$search@usstable@@h@@qaehxz),該符號在函式 _main 中被引用

這個問題是關於模版類的成員函式的定義方法的問題。我按照普通類的寫法,在function.h中宣告類的成員函式,在function.cpp中寫該函式的定義,然後在main.cpp中include檔案,編譯時把main.cpp和function.cpp放在同乙個編譯單元裡面。按理這樣就能生成可執行檔案了,但是鏈結時卻報以上錯誤。

原因是模版類在編譯時是在使用的地方才例項化,但不同的.cpp檔案是在link時才相互關聯,因此編譯main.cpp時只例項化了函式的宣告,並且認為在某個地方已經例項化了函式的定義,悲劇的是編譯function.cpp時並沒有給main.cpp中的這個用法做例項化,於是linker就找不到main.cpp所需要的函式定義了。

於是只有兩種解決辦法,或者在function.cpp中給需要的例項化顯示地做定義(這樣做擴充套件性就很差),或者把template函式的定義也放在.h檔案中。

**討論了更加深入的解決方案,複製如下:

於是我和@吳磊達人討論為什麼c++沒辦法直接在編譯時跨檔案例項化template,結論是源於c的單檔案編譯單元的效率考慮,使得編譯時(鏈結之前)是沒辦法知道其他編譯單元到底需要什麼例項。如果linker能給compiler反饋機制,使得linker之後還能再編譯一遍給做必要的例項化,應該能提供這個特性(填上這個反直覺的坑)了,或者在編譯之前專門做一遍預編譯,給每個使用的template跨檔案標記出需要的例項化,從而編譯時就能解決這個問題了。

systemtap embedded C 踩坑筆記

官方文件 systemtap的embedded c中,不能 include 也不能用printf和print。那怎麼列印呢?用stap printf。用法與printf一樣。還可以訪問cript中的全域性變數。官方文件中的示例 global var global var2 100 function ...

Aggregation MongoDB踩坑記錄

對某些篩選條件進行分頁查詢,開始每一頁的有效data都不足pagesize,最後發現,aggregation 的pipeline是有先後順序的。錯誤 agg aggregation.newaggregation aggregation.skip curpage 1 pagesize aggregat...

樹莓派c 開發踩坑

這幾年用慣了高階語言,c 當年還是c99標準的,尋思這回用用c 最新的特性看看,比如在高階語言中的明顯降低耦合性的自定義事件,這是第乙個坑。首先想到的是個函式指標的巨集 typedef void eventfun eventtype,void 寫完之後發現只能用於靜態函式,看了看c 11特性裡面的 ...