在c++98/03語言標準中,對於源****現的每一處模板例項化,編譯器都需要去做例項化的工作;而在鏈結時,鏈結器還需要移除重複的例項化**。顯然,讓編譯器每次都去進行重複的例項化工作顯然是不必要的,並且聯結器也因此受累。
在現實編碼世界裡,乙個軟體的實現可能會在很多**塊中使用同一種型別去例項化同乙個模板。此時,如果能夠讓編譯器避免此類重複的例項化工作,那麼可以大大提供編譯器的工作效率。因此,人們迫切需要一種手段(一種宣告方式)來告訴編譯器「該處出現的模板例項化工作已在其它編譯單元中完成,不再需要進行例項化」。
於是,乙個新的語言特性————外部模板(extern template)————被納入到c++0x標準中。
在c++98/03中,已經有乙個叫做顯示例項化(explicit instantiation)的語言特性,其目的是指示編譯器立即進行模板例項化操作(即強制例項化)。而外部模板語法就是在顯示例項化指令的語法基礎上進行修改得到的:通過在顯示例項化指令前新增字首extern,從而得到外部模板的語法。
顯示例項化語法:template class vector;
外部模板語法:extern template class vector;
一旦在乙個編譯單元中使用了外部模板宣告(如extern template class vector;),那麼編譯器在編譯該編譯單元時,會跳過與該外部模板宣告匹配的模板例項化(如vector)。
因此,在c++0x中,「模板的顯示例項化指令、外部模板指令和使用」可以模擬為「全域性變數的定義、宣告和使用」。區別僅在於,模板代表**,而變數代表一段連續記憶體空間。
關於外部模板語法的一些約束:
1. 如果外部模板指令出現於乙個編譯單元中,那麼與之對應的顯示例項化必須出現於另乙個編譯單元中或者同乙個編譯單元的後續**中。
2. 外部模板指令不能用於乙個靜態函式(即檔案域函式),但可以用於類靜態函式。(注:這一點是顯而易見的,因為靜態函式沒有外部連線屬性,不可能在本編譯單元之外出現)。
3. 外部模板指令應用於類的成員,而不是類本身。(注:既然已經作用於類的所有成員了,也就相當於作用於類了)
4. 外部模板對於內聯函式是否有用,沒有明確規定,但鼓勵編譯器實現。
外部模板的使用實際依賴於c++98中乙個已有的特性——顯示例項化。例如:
template void fun(t){}
顯式例項化: template void fun(int);
外部模板: extern template void fun(int);
避免編譯器進行重複的例項化,從而減少編譯時間。
二 注意
《深入理解c++11》
如果外部模板宣告出現於某個編譯單元中,那麼與之對應的顯式例項化必須出現於另乙個編譯單元中或者同乙個編譯單元的後續**中;
外部模板不能用於乙個靜態函式(沒有外部鏈結屬性),但可以用於類靜態成員函式。
例子:template.h
#include
// 模板
// 類
template
class a {};
// 靜態成員方法
template
class b ;
};// 靜態普通函式
template
static void f1(t t) ;
// 普通函式
template
void f2(t t) ;
template.cpp
#include "template.h"
// 例項化
void f11()
void f22()
void fm()
main.cpp
#include
#include "template.h"
extern template class a;
extern template void b::f_m(int);
// extern template void f1(int); error
extern template void f2(int);
void f()
int main()
在C 中如何實現模板函式的外部呼叫
export是c 新增的關鍵字,它的作用是實現模板函式的外部呼叫,類似extern關鍵字。為了訪問其他 檔案中的變數或物件,對普通型別 包括基本資料類 結構和類 可以利用關鍵字extern來使用這些變數或物件,但對於模板型別,則可以在標頭檔案中宣告模板類和模板函式,在 檔案中使用關鍵字export來...
django模板匯入js,css等外部檔案
html模板裡面使用了css,但是直接引用不能,搜了一些資料終於搞定,這裡記錄以下。首先是我檔案的tree mysite admin.py,models.py,init py,views.py,test.py,template資料夾 mysite init py,settings.py,urls.p...
C 呼叫外部程式
關於三個sdk函式 winexec,shellexecute,createprocess的其他注意事項 定義標頭檔案 必須定義以下兩個標頭檔案 include 可替換為 windows.h include如果定義了標頭檔案 include 的話就不必定義 include 了。定義路徑 c 中所表示的...