共用方式為


比較標頭單位、模組和先行編譯標頭檔

從歷史上看,您將包含標準程式庫與 指示詞,例如 #include <vector> 。 不過,包含標頭檔的成本很高,因為它們會由包含標頭檔的每個來源檔案重新處理。

先行編譯標頭 (PCH) 會藉由翻譯一次並重複使用結果來加快編譯速度。 但先行編譯的標頭可能難以維護。

在 C++20 中,模組引進為標頭檔與先行編譯標頭的重大改善。

標頭單位是在 C++20 中引進的,用來暫時橋接標頭檔與模組之間的差距。 它們提供模組的一些速度和健全性優點,同時移轉程式碼以使用模組。

然後,C++23 標準程式庫引進了將標準程式庫匯入為具名模組的支援。 這是取用標準程式庫的最快速且最健全的方式。

為了協助您排序不同的選項,本文會比較傳統 #include 方法與先行編譯的標頭、標頭單位,以及匯入具名模組。

下表依編譯器處理速度和健全性來排列,其 #include 速度最慢且最不強固,且 import 最快速且最強固。

方法 摘要
#include 其中一個缺點是它們公開宏和內部實作。 內部實作通常會公開為以底線開頭的函式和類型。 這是一項慣例,表示某個專案是內部實作的一部分,不應使用。

標頭檔很脆弱,因為 #includes 順序可以修改行為或中斷程式碼,而且會受到巨集定義的影響。

標頭檔緩慢編譯。 特別是當多個檔案包含相同的檔案時,因為標頭檔會重新處理多次。
先行編譯標頭 先行編譯標頭 (PCH) 會建立一組標頭檔之編譯器記憶體快照集,以改善編譯時間。 這是重複重建標頭檔改善。

PCH 檔案有限制,使得它們難以維護。

PCH 檔案的速度比 快 #include ,但速度比 慢 import
標頭單位 這是 C++20 中的新功能,可讓您將「行為良好」標頭檔匯入為模組。

標頭單位比 更快 #include ,而且更容易維護、明顯更小,也比預先編譯的標頭檔快(PCH)。

標頭單位是「中間」步驟,旨在協助您轉換至具名模組,以防您依賴標頭檔中定義的宏,因為具名模組不會公開宏。

標頭單位比匯入具名模組慢。

標頭單位不會受到巨集定義的影響,除非在建置標頭單位時在命令列上指定標頭單位,使其比標頭檔更強固。

標頭單位會公開其中定義的宏和內部實作,就像標頭檔所做的一樣,命名模組不會這麼做。

檔案大小的粗略近似值,250 MB 的 PCH 檔案可能會以 80 MB 的標頭檔表示。
單元 這是匯入功能最快且最健全的方式。

C++20 引進了匯入模組的支援。 C++23 標準程式庫介紹本主題中所述的兩個具名模組。

當您匯入 std 時,您會取得標準名稱,例如 std::vectorstd::cout ,但沒有副檔名、沒有內部協助程式,例如 _Sort_unchecked 、 和 沒有宏。

匯入的順序並不重要,因為沒有宏或其他副作用。

檔案大小的粗略近似值,250 MB 的 PCH 檔案可能會以 80 MB 的標頭檔表示,該檔案可能以 25 MB 的模組表示。

具名模組較快,因為當具名模組編譯成 .ifc 檔案和 .obj 檔案時,編譯器會發出結構化的原始程式碼標記法,在匯入模組時可以快速載入。 編譯器可以在發出 .ifc 檔案之前執行一些工作(例如名稱解析),因為具名模組的順序與順序無關且與宏無關,因此在匯入模組時不需要完成這項工作。 相反地,當標頭檔使用 #include 時,其內容必須在每一個轉譯單元中一次又一次地前置處理和編譯。

編譯前標頭是編譯器記憶體快照集,可以降低這些成本,但無法以及具名模組。

如果您在應用程式中使用 C++20 功能和 C++23 標準程式庫,請使用具名模組。

如果您使用 C++20 功能,但想要隨著時間轉換至模組,請在過渡期間使用標頭單位。

如果您無法使用 C++20 功能,請使用 #include 並考慮先行編譯的標頭。

另請參閱

先行編譯標頭檔
C++ 中的模組概觀
教學課程:使用模組匯入 C++ 標準程式庫
逐步解說:將 STL 程式庫匯入為標頭單位
逐步解說:在 Visual C++ 專案中建置和匯入標頭單位