posted on
2011-08-16 08:48
單魚遊弋 閱讀(
0) 編輯
收藏要編譯成dll,就要宣告和實現分開。
首先檔案組織是這樣的(為了簡化,沒有加上編譯成dll的語句)
在 t.h 中(宣告模板函式)
template
<
typename t>
t max(t& t1,t& t2);
在 t.cpp 中(模板函式的實現)
#include"t.h"
template
<
typename t>
t max(t& t1,t& t2)
編譯 t.cpp 很好,通過編譯
在 main.cpp 中(用於測試的)
#include
using namespace std;
#include"t.h"
int main()
編譯 main.cpp 很好,也通過編譯
然後 鏈結執行程式
此時,產生鏈結錯誤了(visual studio 2008環境下)
1>main.obj : error lnk2019: 無法解析的外部符號 "double __cdecl max(double &,double &)" (??$max@n@@yanaan0@z),該符號在函式 _main 中被引用
1>main.obj : error lnk2019: 無法解析的外部符號 "int __cdecl max(int &,int &)" (??$max@h@@yahaah0@z),該符號在函式 _main 中被引用
鏈結器根本沒有找到那兩個函式
發現模板的東西分開成 .h 和 .cpp 是不行的
因為模板是需要在編譯時實現特例化的,光編譯t.cpp是沒有產生可用的函式的。
因此,模板函式/模板類也無法編譯成dll
visual studio 中的系統庫中的stl(標準模板庫)都是以源**的形式呈現的(例如裡面可以看到原始碼的)
看來微軟也沒得好辦法解決這個
所以一般而言 模板的東西 還是都直接寫到 .h 就好了
至於說一定要分開成 .h 和 .cpp的話,用的時候需要#include".cpp"(這個方法很畸形,本質還是直接include了宣告和實現,據說gcc可以分開成 .h 和 .cpp,沒有測試過,應該只是編譯器自動化的幫你include了)
當然這樣還是不能編譯成dll的,我查閱了一下,實在想編譯成dll的話,
必須在編譯模板的時候就進行特例化(其實這樣失去了模板的優勢了,唯一好點的就是可以特例化多種形式)
在 原來的 t.cpp 中加上這段就可以特例化了(也可以加到 t.h 中)
template
int max<
int>(
int& ,
int& ); //int特例化
template double max<
double>(
double& ,
double& ); //double特例化
這樣編譯鏈結執行,就可以了
要編譯成dll的話,加上dll的那個關鍵字就可以了
#ifdef dll_exports
#define dllt_api
__declspec(dllexport)
#else
#define dll_api
__declspec(dllimport)
#endif
c++現在這種編譯時的模板化機制,豈不是讓別個通用模板函式庫的開發商只能開源了?
模板 函式模板 類模板
模板主要是針對資料型別,不同的資料型別卻具有相同的操作形式,比如說,同樣是做入棧,int和double由於資料型別不一樣,需要做兩個棧才能滿足需求,誠然可以使用函式過載,但是終歸棧的操作是一樣的,只是資料型別不一樣。所以在此基礎上,假設,我們首先將所有的資料型別視為乙個大類,將它引數化,等到要用的時...
模板函式,模板類
使用模板函式 include stdafx.h include iostream include string using namespace std template template t add const t t1,const t t2 int tmain int argc,tchar arg...
函式模板,類模板
來自 函式模板 template t getmax t a,t b 呼叫 int i 5,j 6,k long l 10,m 5,n k getmax i,j n getmax l,m 也可以雙型別 template t getmin t a,u b return a呼叫 int i,j long ...