1. 程式人生 > >C++學習:模板編譯模式

C++學習:模板編譯模式

C++函式模板和類模板,如果分別在.h標頭檔案中宣告,在.cpp原始檔中定義,一旦呼叫到該模板,編譯時就會報如下圖所示錯誤。這與模板的編譯模式有關。


C++支援兩種模板編譯模式:包含模式(Inclusion Model)和分離模式(Separation Model)。

包含編譯模式

在包含編譯模式下我們在每個模板被例項化的檔案中包含函式模板的定義並且往往把定義放在標頭檔案中像對行內函數所做的那樣。

分離編譯模式

在分離編譯模式下函式模板的宣告被放在標頭檔案中,在這種模式下,函式模板宣告和定義的組織方式與程式中的非行內函數的宣告和定義組織方式相同。

在分離編譯模式的模板定義中有一個關鍵字export,關鍵字export 告訴編譯器在生成被其他檔案使用的函式模板例項時可能需要這個模板定義編譯器必須保證在生成這些例項時該模板定義是可見的。關鍵字export不需要出現在標頭檔案的模板宣告中。

分離模式使我們能夠很好地將函式模板的介面同其實現分開,進而組織好程式以便把函式模板的介面放到標頭檔案中,而把實現放在文字檔案中。但是,並不是所有的編譯器都支援分離模式,即使支援也未必總能支援得很好。支援分離模式需要更復雜的程式設計環境,所以它們不能在所有C++編譯器實現中提供。

目前VC、VS的任何版本皆不支援分離模式!
g++不支援模板例項化的export關鍵字(此關鍵字的這個用法已在C++11標準裡被取消)。

大部分編譯器在編譯模板時都使用包含模式。當未使用這個函式模版或類模版,編譯器並不例項化它,當被使用時,編譯器需要例項化它,因為編譯器是一次只能處理一個編譯單元, 也就是一次處理一個cpp檔案,所以例項化時需要看到該模板的完整定義。所以都放在標頭檔案中。這不同於普通的函式, 在使用普通的函式時,編譯時只需看到該函式的宣告即可編譯, 而在連結時由連結器來確定該函式的實體。