編譯器只有在用到模板時,如呼叫了函式模板或呼叫了類模板的物件的時候,編譯器才產生特定型別的模板例項。
編譯時,模板與普通函式、類的區別:
標準 c++ 編譯模板**的兩種模型:包含編譯、分別編譯
相同點:構造程式的方式相同----類定義和函式宣告放在標頭檔案中,而函式定義和成員定義放在原始檔中。所有編譯器都支援包含編譯模型,只有一些編譯器支援分別編譯模型。不同點:編譯器怎樣使用來自原始檔的定義,包含編譯必須看到所有模版定義,而分別編譯會自動跟蹤所有模版定義。
一、包含編譯模型
在包含編譯模型中,編譯器必須看到用到的所有模板的定義。一般而言,可以通過在宣告函式模板或類模板的標頭檔案中新增一條#include指示使定義可用,該#include 引入了包含相關定義的原始檔:
// 標頭檔案 compare.h
#ifndef compare_h
#define compare
template int compare( const t&, const t& );
// 其他宣告
#include "compare.cpp" //獲得compare 的定義
#endif
// 原始檔 compare.cpp
#include "compare.h"
template int compare( const t &v1, const t &v2 )
// 其他定義
包含編譯使得標頭檔案和實現檔案的分享,但是需要保證編譯器在編譯使用模板的**時能看到兩種檔案。
某些使用包含模型的編譯器,可以產生多個例項。如果兩個或多個單獨編譯的原始檔使用同一模板,這些編譯器將為每個檔案中的模板產生乙個例項。通常,這種方法意味著給定模板將例項化超過一次。在預鏈結階段,編譯器會選擇乙個例項化而丟棄其他的。
包含編譯在包含定義檔案時,注意:
二、分別編譯模型
通常用export 關鍵字
使編譯器能夠跟蹤相關的模板定義。export 關鍵字能夠指明給定的定義可能會需要在其他檔案中產生例項化。在乙個程式中,
乙個模板只能定義為匯出一次
。編譯器在需要產生這些例項化時計算出怎樣定位模板定義。export 關鍵字不必在模板宣告中出現。
函式模板:一般在函式模板的定義中指明export,這是通過在關鍵字template 之前包含 export 關鍵字而實現的:
// 標頭檔案 compare.h
#ifndef compare_h
#define compare
template int compare( const t&, const t& );
// 其他宣告
#endif
// 原始檔 compare.cpp
#include "compare.h"
export template int compare( const t &v1, const t &v2 ) //export指明函式為匯出型別
// 其他定義
類模板:標頭檔案中的類定義體不應該使用關鍵字 export,如果在標頭檔案中使用了 export,則該標頭檔案只能被程式中的乙個原始檔使用。應該在類的實現檔案中使用 export:
// 標頭檔案 queue.h
#ifndef queue_h
#define queue_h
template class queue;
// 其他宣告
#endif
// 原始檔 queue.cpp
#include "queue.h"
export template class queue; //指明類queue為export匯出型別
template queue::func()
// 其他定義
我目前使用的 vs2012不支援分別編譯模型,包含編譯通過。 C 學習筆記60 模板編譯模型
只說包含模型吧。高大上的分離模型,編譯器支援不好,雖然是標準中明文規定的。詳見 檔案組織形式如下 現在假設共有3個檔案,friend.cpp實現模板函式定義 friend.h實現模板函式宣告 main.c實現函式呼叫。friend.cpp檔案 注意這裡沒有標頭檔案包含 templateint com...
c 模板編譯
如何組織編寫模板程式 前言 常遇到詢問使用模板到底是否容易的問題,我的回答是 模板的使用是容易的,但組織編寫卻不容易 看看我們幾乎每天都能遇到的模板類吧,如stl,atl,wtl,以及boost的模板類,都能體會到這樣的滋味 介面簡單,操作複雜。我在5年前開始使用模板,那時我看到了mfc的容器類。直...
C 模板編譯問題
今天做乙個矩陣類,打算使用模板,結果出現了問題。問題描述 像往常一樣在matrix.h檔案中定義了乙個模板類,如下 template class matrix matrix 在matrix.cpp檔案中定義類成員函式,如下 template matrix matrix 編譯不通過 最後找到解決辦法,...