[問題] C++ template 宣告和函數分開寫

看板C_and_CPP作者 (Jimmy)時間12年前 (2013/05/16 21:45), 編輯推噓1(1022)
留言23則, 5人參與, 最新討論串1/1
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) g++ linux 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) 問題(Question) *[m 在myprint.hpp裡面宣告函數型態 template <class T> myprint..., 在myprint.cpp裡面定義函數, test_mypint.cpp裡面用main呼叫myprit, compile時找不到函數。 餵入的資料(Input): 沒有 預期的正確結果(Expected Output): 錯誤結果(Wrong Output): /tmp/cc3Zk2SY.o: In function `main': test_myprint.cpp:(.text+0x63): undefined reference to `void myprint<double>(double*, int, char*)' collect2: ld returned 1 exit status 程式碼(Code):(請善用置底文網頁, 記得排版) =================myprint.hpp========================== template <class T> void myprint(T *b, int n , char file_name[]); ====================================================== =================myprint.cpp========================== #include <iostream> #include <fstream> #include <cassert> #include "myprint.hpp" using namespace std; template <class T> void myprint(T *b, int n , char file_name[]){ int i ; ofstream myfile; myfile.open (file_name); assert(myfile.is_open()); for (i =0 ;i<n;i++) myfile << b[i] << endl; myfile.close(); return ; } ======================================================= ==================main.cpp============================= #include <cstdlib> #include "myprint.hpp" int main(){ char my_name [80] = "test_print_name.txt"; double *b = (double*)malloc(sizeof(double)*10); myprint<double>(b, 10 , my_name); free(b); return 0; } ======================================================== ===============command ================================= g++ myprint.cpp test_myprint.cpp ======================================================== 補充說明(Supplement): 我找到的資料是有說template不能分開寫,但是我不太懂是指什麼不能分開寫。 謝謝大家。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.112.51.116 ※ 編輯: hjmeric 來自: 140.112.51.116 (05/16 21:47)

05/16 21:48, , 1F
就是你 myprint(){...} 裡面的東西不能寫在 test_myprint
05/16 21:48, 1F

05/16 21:48, , 2F
看不到的地方。如果看不到它不知道怎麼"產生函式"
05/16 21:48, 2F

05/16 21:49, , 3F
記住 template 並不是一個 function,只是一個樣本
05/16 21:49, 3F

05/16 21:57, , 4F
通常實作都是把myprint.cpp的內容丟進 myprint.hpp?
05/16 21:57, 4F

05/16 21:58, , 5F
然後再用main去include myprint.hpp 這樣? 謝謝你。
05/16 21:58, 5F

05/16 22:04, , 6F
是的,以前雖有 export 這東西不過沒有人做,新版也拿掉了
05/16 22:04, 6F

05/16 22:08, , 7F
了解了,謝謝你。
05/16 22:08, 7F

05/17 00:36, , 8F
可以分開寫... 也就是 header 裡面只放 template 宣告
05/17 00:36, 8F

05/17 00:37, , 9F
不過在某些實作檔(.cpp)就必須explicit instantiation
05/17 00:37, 9F

05/17 00:38, , 10F
把你要的 function 實體生出來, link 的時候找到實體
05/17 00:38, 10F

05/17 00:38, , 11F
就可以真的去呼叫它, 一般比較懶方法就是把模板都寫在
05/17 00:38, 11F

05/17 00:39, , 12F
header裡, 讓具現化的動作交給編譯器來, 但是這樣因為
05/17 00:39, 12F

05/17 00:41, , 13F
每個編譯單元內可能生出一樣的實體, 最後連結時因為要
05/17 00:41, 13F

05/17 00:42, , 14F
排除重複的所以會稍微久一點. 所以是看你的需求來決定
05/17 00:42, 14F

05/17 00:43, , 15F
怎麼寫, 我會傾向於內建型態寫一個模板, 但是自己具現
05/17 00:43, 15F

05/17 00:44, , 16F
化所有需要的實體, user defined type再寫另一個模板
05/17 00:44, 16F

05/17 00:44, , 17F
這個實作就會放在header裡
05/17 00:44, 17F

05/17 00:46, , 18F
最好使用 SFINAE 來限制編譯器能具現化的實體種類
05/17 00:46, 18F

05/17 01:00, , 19F
05/17 01:00, 19F

05/17 01:48, , 20F
感謝板主大大的補充!最一開始的觀念就是樣本和實體的差別
05/17 01:48, 20F

05/17 08:24, , 21F
感謝版主大大的補充!
05/17 08:24, 21F

05/17 13:09, , 22F
extern template?
05/17 13:09, 22F

05/17 17:50, , 23F
謝謝各位的分享。
05/17 17:50, 23F
文章代碼(AID): #1HbECMs9 (C_and_CPP)