關於模板函式 模板類編譯成DLL

2021-06-26 05:10:47 字數 1775 閱讀 7275

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 ...