共用方式為


逐步解說:將 STL 程式庫匯入為標頭單位

本逐步解說示範如何在 Visual Studio 中將 C++ 標準範本庫 (STL) 程式庫匯入為標頭單位。 如需更快速且更健全的方式匯入標準程式庫,請參閱 教學課程:使用模組 匯入 C++ 標準程式庫。

將 STL 標頭匯入為標頭單位比使用 先行編譯標頭檔 更簡單。 標頭單位更容易設定及使用、在磁片上大幅縮小、提供類似的效能優點,而且比 共用 PCH 更有彈性。

如需哪些標頭單位及其提供之優點的詳細資訊,請參閱 什麼是標頭單位? 。 若要比較標頭單位與其他匯入標準程式庫的方式,請參閱 比較標頭單位、模組和先行編譯標頭

必要條件

若要使用標頭單位,請使用 Visual Studio 2022 或更新版本,或 Visual Studio 2019 16.11 版或更新版本。 使用 /std:c++20 標頭單位需要選項(或更新版本)。

匯入 STL 標頭作為標頭單位的兩種方法

您必須先將 STL 標頭編譯為標頭單位,才能匯入 STL 標頭。 標頭單位是標頭檔二進位標記法。 它有延伸 .ifc 模組。

建議的方法是建立靜態程式庫,其中包含您想要使用之 STL 標頭的建置標頭單位。 然後參考該程式庫及其 import 標頭單位。 這種方法可能會導致更快速的組建和更好的重複使用。 若要試用此方法,請參閱 方法 1:建立 STL 程式庫標頭單位 的靜態程式庫。

另一種方法是讓 Visual Studio 掃描您 #include 專案中的 STL 標頭、將它們編譯成標頭單位, import 而不是 #include 那些標頭。 如果您有大型程式碼基底,因為不需要變更原始程式碼,這個方法就很有用。 這種方法比靜態程式庫方法更不具彈性,因為它本身無法重複使用其他專案中的建置標頭單位。 但是,您仍然可以取得將個別 STL 程式庫匯入為標頭單位的效能優勢。 若要試用此方法,請參閱 方法 2:掃描包含要匯 入的 STL 標頭。

方法 1:建立 STL 程式庫標頭單位的靜態程式庫

使用 STL 程式庫做為標頭單位的建議方式是建立一或多個靜態程式庫專案。 這些專案應該包含您想要使用的 STL 程式庫標頭單位。 然後,參考程式庫專案以取用這些 STL 標頭單位。 這類似于使用 共用先行編譯標頭 ,但比較容易。

靜態程式庫專案中內建的標頭單位(和模組)會自動可供參考專案,因為專案系統會自動將適當的 /headerUnit 命令列選項新增至編譯器,以便參考專案可以匯入標頭單位。

此方法可確保特定標頭的標頭單位只會建置一次。 它可讓您匯入部分或所有標頭單位,這無法使用 PCH。 您可以依任何順序包含標頭單位。

在下列範例中,您會建立靜態程式庫專案,其中包含 <iostream><vector> 標頭單位。 建置方案之後,您將從另一個 C++ 專案參考此共用標頭單元專案。 在任何地方或 import <vector>; 找到 import <iostream>; 時,都會使用該程式庫的建置標頭單位,而不是使用預處理器轉譯標頭。 當多個檔案中包含相同的標頭時,它可改善組建效能,例如 PCH 檔案。 標頭不一定由包含它的檔案來回處理。 相反地,已處理的已編譯標頭單位會匯入。

若要建立包含 STL 程式庫和 <vector> 的靜態程式庫 <iostream> ,請遵循下列步驟:

  1. 建立空的 C++ 專案。 將其命名為 SharedPrj
    從 [建立新專案] 視窗中可用的 專案類型選取 [C++ 的空白 專案 ]:Screenshot that shows creating a new empty C++ project.

  2. 將新的 C++ 檔案新增至專案。 將檔案的內容變更為:

    import <iostream>;
    import <vector>;
    

設定專案屬性

設定專案屬性以共用此專案的標頭單位:

  1. 在 Visual Studio 主功能表上,選取 [專案 > 共用][Prj 屬性] 以開啟專案 [屬性 頁] 對話方塊:Screenshot that shows settings for Configuration Type and C++ Language Standard.
  2. 在 [組態] 下拉式清單中選取 [所有組態 ],然後在 [平臺 ] 下拉式清單中選取 [ 所有平臺 ]。 這些設定可確保您的變更適用于您要建置偵錯或發行。
  3. 在專案 [屬性頁] 對話方塊的左窗格中,選取 [組態屬性 > 一般]。
  4. 將 [ 組態類型] 選項變更為 靜態程式庫 (.lib)
  5. 將 C++ 語言標準 變更 ISO C++20 標準 (/std:c++20) (或更新版本)。
  6. 在專案 [屬性頁] 對話方塊的左窗格中,選取 [組態屬性 > C/C++ > 一般]。
  7. 在 [ 掃描模組相依性 的來源] 下拉式清單中,選取 [ ]。 (此選項會讓編譯器掃描程式碼中的相依性,這些相依性可以內建于標頭單位中): Screenshot that shows the scan module dependencies property setting.
  8. 選擇 [ 確定 ] 以關閉 [屬性頁] 對話方塊。 選取 主功能表上的 [建置方案 ] 來建置方案,以建 > 置方案。

參考標頭單元程式庫

若要從靜態程式庫匯 <iostream> 入 和 <vector> 作為標頭單位,請建立參考靜態程式庫的專案,如下所示:

  1. 當目前的方案仍然開啟時,在 Visual Studio 功能表上,選取 [ 檔案 > 新增 > 專案]。

  2. 在 [ 建立新專案 精靈] 中,選取 C++ 主控台應用程式 範本,然後選擇 [ 下一步 ]。

  3. 將新專案 命名為逐步解說 。 將 [方案 ] 下拉式 清單變更為 [ 新增至方案 ]。 選擇 [建立] 以建立專案,並將其新增至您的方案。

  4. 變更 Walkthrough.cpp 原始程式檔的內容 ,如下所示:

    import <iostream>;
    import <vector>;
    
    int main()
    {
        std::vector<int> numbers = {0, 1, 2};
        std::cout << numbers[1];
    }
    

標頭單位需要 /std:c++20 選項(或更新版本)。 使用下列步驟設定語言標準:

  1. 方案總管 中,以滑鼠右鍵按一下 [逐步解說 ] 專案,然後選取 [ 屬性] 以開啟 [屬性 頁] 對話方塊:Screenshot that shows setting the language standard to the preview version.
  2. 在 [逐步解說專案屬性頁] 對話方塊的 左窗格中,選取 [組態屬性 > 一般]。
  3. 在 [ C++ 語言標準 ] 下拉式清單中,選取 [ISO C++20 標準] (/std:c++20) (或更新版本)。
  4. 選擇 [ 確定 ] 以關閉 [屬性頁] 對話方塊。

在逐步 解說專案中,使用下列步驟新增 SharedPrj 專案的參考

  1. 在逐步 解說 專案中,選取 [ 參考] 節點,然後選取 [ 新增參考 ]。 在專案清單中選取 SharedPrj Screenshot that shows the Add Reference dialog. It's used to add a reference to the Walkthrough project.新增此參考時,每當 import 逐步解說專案中的 符合 SharedPrj 中其中一個建置的標頭單位時,建置系統就會使用 SharedPrj 建置的標頭單位。
  2. 選擇 [ 確定 ] 以關閉 [ 新增參考] 對話方塊。
  3. 以滑鼠右鍵按一下 [ 逐步解 說] 專案,然後選取 [ 設定為啟始專案 ]。
  4. 建置方案。 (使用 在主功能表上建 > 置建置方案。 執行它以查看它產生預期的輸出:1

這種方法的優點是,您可以從任何專案參考靜態程式庫專案,以重複使用其中的標頭單位。 在此範例中,靜態程式庫包含 <vector><iostream> 標頭單位。

您可以建立整合型靜態程式庫專案,其中包含您想要從各種專案匯入的所有常用 STL 標頭。 或者,您可以針對您想要匯入為標頭單位的不同 STL 程式庫群組,建立較小的共用程式庫專案。 然後視需要參考這些共用標頭單位專案。

結果應該會增加建置輸送量,因為匯入標頭單位會大幅減少編譯器必須執行的工作。

當您將此方法與您自己的專案搭配使用時,請使用與參考它的專案相容的編譯器選項來建置靜態程式庫專案。 例如,應該使用 /EHsc 編譯器選項來建置 STL 專案,以開啟例外狀況處理,因此參考靜態程式庫專案的專案也應該如此。

使用 /translateInclude

編譯 /translateInclude 程式選項(在 C/C++ > 一般 > 翻譯包含至匯 入下的 [專案屬性頁] 對話方塊中提供,可讓您更輕鬆地在 STL 程式庫的舊專案中 #include 使用標頭單元程式庫。 它不需要在專案中將 指示詞變更 #includeimport ,同時仍可讓您匯入標頭單位,而不是包含它們。

例如,如果您在專案中擁有 #include <vector> ,而且參考包含 標頭單位的 <vector> 靜態程式庫,則不需要在原始程式碼中手動變更 #include <vector>import <vector>; 。 相反地,編譯器會自動將 視為 #include <vector>import <vector>; 。 如需此方法的詳細資訊,請參閱 方法 2:掃描包含要匯 入的 STL 標頭。 並非所有 STL 標頭檔都可以編譯為標頭單位。 header-units.json隨附的 Visual Studio 會列出哪些 STL 標頭檔可以編譯成標頭單位。 依賴宏來指定其行為的標頭,通常無法編譯成標頭單位。

#include未參考標頭單位的語句會被視為一般 #include

在專案之間重複使用標頭單位

靜態程式庫專案所建置的標頭單位會自動提供給所有直接或間接參考專案。 有專案設定可讓您選取哪些標頭單位應該會自動提供給所有參考專案使用。 這些設定位於 VC++ 目錄 下的 專案設定中。

  1. 方案總管 中,以滑鼠右鍵按一下專案,然後選取 [屬性] 以開啟 [屬性 頁] 對話方塊。
  2. 在對話方塊的左窗格中,選取 [組態屬性 > VC++ 目錄 ]:Screenshot that shows public project content properties, like Public Include Directories and All Header Files are Public.

下列屬性可控制建置系統的標頭單位可見度:

  • 公用 Include 目錄 會指定標頭單位的專案目錄,這些標頭單位應該會自動新增至參考專案中的 Include 路徑。
  • 公用 C++ 模組目錄 會指定哪些專案目錄包含應該可供參考專案的標頭單位。 這個屬性可讓您公開某些標頭單位。 其他專案可以看到它,因此請將您想要在這裡共用的標頭單位放在這裡。 如果您使用此設定,為了方便起見,請指定 公用 Include 目錄 ,以自動將公用標頭新增至參考專案中的 Include 路徑。
  • 所有模組都是公用 :當您使用建置為 DLL 專案的一部分的標頭單位時,符號必須從 DLL 匯出。 若要自動匯出模組符號,請將此屬性設定為 [是 ]。

使用預先建置的模組檔案

一般而言,在解決方案之間重複使用標頭單位最簡單的方式,就是從每個解決方案參考共用標頭單位專案。

如果您必須使用沒有專案的建置標頭單位,您可以指定建置 .ifc 檔案的位置,以便將其匯入方案中。 若要存取此設定:

  1. 在主功能表上,選取 [專案 > 屬性] 以開啟專案 [屬性 頁] 對話方塊。
  2. 在對話方塊的左窗格中,選取 [組態屬性 > C/C++ > 一般]。
  3. [其他模組相依性 ] 中,新增要參考的模組,並以分號分隔。 以下是用於 其他模組相依性 之格式的範例: ModuleName1=Path\To\ModuleName1.ifc; ModuleName2=Path\To\ModuleName2.ifcScreenshot showing project Property Pages properties under Configuration Properties, C/C++, General, with Additional Module Dependencies selected.

選取標頭單位的多個複本

如果您參考建置多個標頭單位的專案,請以相同名稱或相同的標頭檔,指定要使用的專案。 例如,您可能使用不同的編譯器設定所建置的標頭單元版本,而且必須指定符合專案設定的標頭單位。

使用專案的 [其他標頭單位相依性 ] 屬性,藉由指定要使用的標頭單位來解決衝突。 否則,無法預測挑選哪一個。

若要設定 [其他標頭單位相依性 ] 屬性:

  1. 在主功能表上,選取 [專案 > 屬性] 以開啟專案 [屬性 頁] 對話方塊。
  2. 在對話方塊的左窗格中,選取 [組態屬性 > C/C++ > 一般]。
  3. 指定要用於 其他標頭單位相依性的 模組或頭單元檔案,以解決衝突。 針對 其他標頭單位相依性 使用此格式: Path\To\Header1.h= Path\To\HeaderUnit1.ifc;Path\To\Header2.h= Path\To\ HeaderUnit2.ifcScreenshot that shows the Additional Header Unit Dependencies setting in the project Property Pages dialog.

重要

請確定共用標頭單位的專案是使用相容的編譯選項所建置。 如果您在實作與建立標頭單位不同的標頭單位時使用編譯選項,編譯器將會發出警告。

注意

若要使用作為 DLL 專案的一部分建置的標頭單位,請將 [所有模組] 設為 [是 ]。

方法 2:掃描包含要匯入的 STL 標頭

另一個匯入 STL 程式庫的方式是讓 Visual Studio 掃描您 #include 專案中的 STL 標頭,並將其編譯成標頭單位。 編譯器接著會匯入,而不是包含這些標頭。

當您的專案包含許多檔案的 STL 標頭檔,或建置輸送量不重要時,此選項就很方便。 此選項不保證特定標頭檔標頭單位只會建置一次。 不過,如果您有大型程式碼基底,就很有用:您不需要變更原始程式碼,就能利用您使用之許多 STL 程式庫的標頭單位優點。

這種方法比靜態程式庫方法還不具彈性,因為它本身無法重複使用其他專案中的建置標頭單位。 此方法可能不適用於較大的專案:它不保證最佳的建置時間,因為所有來源都必須掃描 #include 語句。

並非所有標頭檔都可以自動轉換成標頭單位。 例如,相依于透過宏進行條件式編譯的標頭不應該轉換成標頭單位。 指定編譯器時 /translateInclude 所使用的 STL 標頭檔案格式 header-units.json 為 allowlist。 它會決定哪些 STL 標頭可以編譯成標頭單位。 檔案 header-units.json 位於 Visual Studio 的安裝目錄底下。 例如: %ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json 。 如果 STL 標頭檔不在清單中,則會將其視為一般 #include ,而不是將它匯入為標頭單位。 檔案的另 header-units.json 一個優點是,它會防止內建標頭單位中的符號重複。 也就是說,如果編譯標頭單位多次帶入另一個程式庫標頭,則不會複製符號。

若要試用此方法,請建立包含兩個 STL 程式庫的專案。 然後,變更專案的屬性,使其將程式庫匯入為標頭單位,而不是包含它們,如下一節所述。

建立 C++ 主控台應用程式專案

請遵循下列步驟來建立包含兩個 STL 程式庫的專案: <iostream><vector>

  1. 在 Visual Studio 中,建立新的 C++ 主控台應用程式專案。

  2. 取代來源檔案的內容,如下所示:

    #include <iostream>;
    #include <vector>;
    
    int main()
    {
        std::vector<int> numbers = {0, 1, 2};
        std::cout << numbers[1];
    }
    

設定專案選項並執行專案

下列步驟會設定選項,讓編譯器掃描包含的標頭,以轉譯成標頭單位。 它們也會設定選項,讓編譯器將 視為 #include 您已針對可視為標頭單位的標頭檔撰寫 import

  1. 在主功能表上,選取 [專案 > 屬性] 以開啟專案 [屬性 頁] 對話方塊。
  2. 在 [組態] 下拉式清單中選取 [所有組態 ],然後在 [平臺 ] 下拉式清單中選取 [ 所有平臺 ]。 這些設定可確保您的變更適用于您要建置偵錯或發行,以及其他組態。
  3. 在對話方塊的左窗格中,選取 [組態屬性 > C/C++ > 一般]。
  4. 將模組相依性的 掃描來源設定 [是 ]。 此設定可確保所有相容的標頭檔都會編譯成標頭單位。
  5. 將 [翻譯包含] 設定 為 [匯入 ] 為 [是 ]。 此設定會將檔案中列出的 header-unit.json STL 標頭檔編譯為標頭單位,然後匯入它們,而不是使用預處理器將它們匯入 #includeScreenshot that shows the scan module dependencies property setting in the project Property Pages.
  6. 選擇 [ 確定 ] 以儲存您的變更,並關閉 [屬性頁] 對話方塊。

/std:c++20使用標頭單位需要選項或更新版本。 若要變更編譯器所使用的 C++ 語言標準:

  1. 在主功能表上,選取 [專案 > 屬性] 以開啟專案 [屬性 頁] 對話方塊。
  2. 在 [組態] 下拉式清單中選取 [所有組態 ],然後在 [平臺 ] 下拉式清單中選取 [ 所有平臺 ]。 這些設定可確保您的變更適用于您要建置偵錯或發行,以及其他組態。
  3. 在專案 [屬性頁] 對話方塊的左窗格中,選取 [組態屬性 > 一般]。
  4. 在 [ C++ 語言標準 ] 下拉式清單中,選取 [ISO C++20 標準] (/std:c++20) (或更新版本)。
  5. 選擇 [ 確定 ] 以儲存您的變更,並關閉 [屬性頁] 對話方塊。
  6. 從主功能表中,選取 [建 > 置方案] 來建置方案。

執行解決方案以確認其產生預期的輸出: 1

使用此方法的主要考慮是便利性與掃描所有檔案的成本之間的平衡,以判斷要建置為標頭單位的標頭檔。

另請參閱

比較標頭單位、模組和先行編譯標頭
教學課程:使用模組匯入 C++ 標準程式庫
逐步解說:在 Visual C++ 專案中建置和匯入標頭單位
/translateInclude