Condividi tramite


Procedura dettagliata: Importare librerie STL come unità di intestazione

Questa procedura dettagliata illustra come importare librerie STL (Standard Template Library) C++ come unità di intestazione in Visual Studio. Per un modo ancora più rapido e affidabile per importare la libreria standard, vedere Esercitazione: Importare la libreria standard C++ usando i moduli.

L'importazione di un'intestazione STL come unità di intestazione è più semplice rispetto all'uso di file di intestazione precompilati. Le unità di intestazione sono più facili da configurare e usare, sono sostanzialmente più piccole su disco, offrono vantaggi di prestazioni simili e sono più flessibili rispetto a un PCH condiviso.

Per informazioni più dettagliate sulle unità di intestazione e sui vantaggi offerti, vedere Che cos'è un'unità di intestazione?. Per confrontare le unità di intestazione con altri modi per importare la libreria standard, vedere Confrontare unità di intestazione, moduli e intestazioni precompilate.

Prerequisiti

Per usare le unità di intestazione, usare Visual Studio 2022 o versione successiva o Visual Studio 2019 versione 16.11 o successiva. L'opzione /std:c++20 (o versione successiva) è necessaria per usare le unità di intestazione.

Due approcci per importare intestazioni STL come unità di intestazione

Prima di poter importare un'intestazione STL, è necessario compilarla in un'unità di intestazione. Un'unità di intestazione è una rappresentazione binaria di un file di intestazione. Ha un'estensione .ifc .

L'approccio consigliato consiste nel creare una libreria statica contenente le unità di intestazione compilate per le intestazioni STL da usare. Quindi fare riferimento a tale libreria e import alle relative unità di intestazione. Questo approccio può comportare compilazioni più veloci e un riutilizzo migliore. Per provare questo approccio, vedere Approccio 1: Creare una libreria statica di unità di intestazione della libreria STL.

Un altro approccio consiste nel fare in modo che Visual Studio analizzi le intestazioni #include STL nel progetto, le compili in unità di intestazione e import invece di #include quelle intestazioni. Questo approccio è utile se si dispone di una codebase di grandi dimensioni, perché non è necessario modificare il codice sorgente. Questo approccio è meno flessibile rispetto all'approccio alla libreria statica, perché non si presta a riutilizzare le unità di intestazione compilate in altri progetti. Tuttavia, si ottiene comunque il vantaggio delle prestazioni dell'importazione di singole librerie STL come unità di intestazione. Per provare questo approccio, vedere Approccio 2: Analisi include le intestazioni STL da importare.

Approccio 1: Creare una libreria statica di unità di intestazione della libreria STL

Il modo consigliato per usare le librerie STL come unità di intestazione consiste nel creare uno o più progetti di libreria statica. Questi progetti devono essere costituiti dalle unità di intestazione della libreria STL da usare. Quindi, fare riferimento ai progetti di libreria per utilizzare tali unità di intestazione STL. È simile all'uso di intestazioni precompilate condivise, ma più semplice.

Le unità di intestazione (e i moduli) compilati in un progetto di libreria statica sono automaticamente disponibili per fare riferimento ai progetti perché il sistema di progetto aggiunge automaticamente l'opzione della riga di comando appropriata /headerUnit al compilatore in modo che i progetti di riferimento possano importare le unità di intestazione.

Questo approccio garantisce che l'unità di intestazione per una particolare intestazione venga compilata una sola volta. Consente di importare alcune o tutte le unità di intestazione, che non è possibile con un PCH. È possibile includere unità di intestazione in qualsiasi ordine.

Nell'esempio seguente viene creato un progetto di libreria statica costituito dalle unità di <iostream> intestazione e <vector> . Dopo aver compilato la soluzione, si farà riferimento a questo progetto di unità di intestazione condivisa da un altro progetto C++. Ovunque import <iostream>; o import <vector>; si trova, l'unità di intestazione compilata per tale libreria viene usata invece di tradurre l'intestazione con il preprocessore. Migliora le prestazioni di compilazione, come i file PCH, quando la stessa intestazione è inclusa in più file. L'intestazione non dovrà essere elaborata più o più in base ai file che lo includono. Viene invece importata l'unità di intestazione compilata già elaborata.

Per creare una libreria statica contenente le librerie <iostream> STL e <vector>, seguire questa procedura:

  1. Creare un progetto C++ vuoto. Denominarlo SharedPrj.
    Selezionare Progetto vuoto per C++ dai tipi di progetto disponibili nella finestra Crea un nuovo progetto : Screenshot che mostra la creazione di un nuovo progetto C++ vuoto.

  2. Aggiungere un nuovo file C++ al progetto. Modificare il contenuto del file in:

    import <iostream>;
    import <vector>;
    

Impostare le proprietà del progetto

Impostare le proprietà del progetto per condividere le unità di intestazione da questo progetto:

  1. Nel menu principale di Visual Studio selezionare Project>SharedPrj Properties per aprire la finestra di dialogo Pagine delle proprietà del progetto: Screenshot che mostra le impostazioni per Tipo di configurazione e Standard del linguaggio C++.
  2. Selezionare Tutte le configurazioni nell'elenco a discesa Configurazione e quindi selezionare Tutte le piattaforme nell'elenco a discesa Piattaforma . Queste impostazioni assicurano che le modifiche vengano applicate indipendentemente dalla compilazione per il debug o la versione.
  3. Nel riquadro sinistro della finestra di dialogo Pagine delle proprietà del progetto selezionare Proprietà>di configurazione Generale.
  4. Modificare l'opzione Tipo di configurazione su Libreria statica (.lib).
  5. Modificare lo standard del linguaggio C++ in ISO C++20 Standard (/std:c++20) (o versione successiva).
  6. Nel riquadro sinistro della finestra di dialogo Pagine delle proprietà del progetto selezionare Proprietà>di configurazione C/C++>Generale.
  7. Nell'elenco a discesa Analizza origini per dipendenze modulo selezionare . Questa opzione fa sì che il compilatore analizzi il codice per individuare le dipendenze che possono essere incorporate in unità di intestazione: Screenshot che mostra l'impostazione della proprietà delle dipendenze del modulo di analisi.
  8. Scegliere OK per chiudere la finestra di dialogo Pagine delle proprietà del progetto. Compilare la soluzione selezionando Compila>soluzione nel menu principale.

Fare riferimento alla libreria di unità di intestazione

Per importare <iostream> e <vector> come unità di intestazione dalla libreria statica, creare un progetto che faccia riferimento alla libreria statica come indicato di seguito:

  1. Con la soluzione corrente ancora aperta, scegliere File>Aggiungi>nuovo progetto dal menu di Visual Studio.

  2. Nella procedura guidata Crea un nuovo progetto selezionare il modello App console C++ e scegliere Avanti.

  3. Assegnare al nuovo progetto il nome Procedura dettagliata. Modificare l'elenco a discesa Soluzione in Aggiungi alla soluzione. Scegliere Crea per creare il progetto e aggiungerlo alla soluzione.

  4. Modificare il contenuto del file di origine Walkthrough.cpp come segue:

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

Le unità di intestazione richiedono l'opzione /std:c++20 (o versione successiva). Impostare lo standard linguistico attenendosi alla procedura seguente:

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto Procedura dettagliata e scegliere Proprietà per aprire la finestra di dialogo Pagine delle proprietà del progetto:Screenshot che mostra l'impostazione dello standard linguistico sulla versione di anteprima.
  2. Nel riquadro sinistro della finestra di dialogo Pagine delle proprietà del progetto Procedura dettagliata selezionare Proprietà>di configurazione Generale.
  3. Nell'elenco a discesa Standard del linguaggio C++ selezionare ISO C++20 Standard (/std:c++20) (o versione successiva).
  4. Scegliere OK per chiudere la finestra di dialogo Pagine delle proprietà del progetto.

Nel progetto Procedura dettagliata aggiungere un riferimento al progetto SharedPrj con la procedura seguente:

  1. Nel progetto Procedura dettagliata selezionare il nodo Riferimenti e quindi selezionare Aggiungi riferimento. Selezionare SharedPrj nell'elenco dei progetti: Screenshot che mostra la finestra di dialogo Aggiungi riferimento. Viene usato per aggiungere un riferimento al progetto Procedura dettagliata. L'aggiunta di questo riferimento fa sì che il sistema di compilazione usi le unità di intestazione compilate da SharedPrj ogni volta che un oggetto import nel progetto Procedura dettagliata corrisponde a una delle unità di intestazione compilate in SharedPrj.
  2. Scegliere OK per chiudere la finestra di dialogo Aggiungi riferimento .
  3. Fare clic con il pulsante destro del mouse sul progetto Procedura dettagliata e scegliere Imposta come progetto di avvio.
  4. Compilare la soluzione. (Usa) Compila>soluzione nel menu principale. Eseguirlo per verificare che produa l'output previsto: 1

Il vantaggio di questo approccio è che è possibile fare riferimento al progetto di libreria statica da qualsiasi progetto per riutilizzare le unità di intestazione in esso contenute. In questo esempio la libreria statica contiene le <vector> unità di intestazione e <iostream> .

È possibile creare un progetto di libreria statica monolitica contenente tutte le intestazioni STL comunemente usate da importare dai vari progetti. In alternativa, è possibile creare progetti di libreria condivisa più piccoli per i diversi raggruppamenti di librerie STL da importare come unità di intestazione. Fare quindi riferimento a tali progetti di unità di intestazione condivisa in base alle esigenze.

Il risultato dovrebbe essere maggiore della velocità effettiva di compilazione perché l'importazione di un'unità di intestazione riduce significativamente il lavoro che il compilatore deve eseguire.

Quando si usa questo approccio con i propri progetti, compilare il progetto di libreria statica con opzioni del compilatore compatibili con il progetto che vi fa riferimento. Ad esempio, i progetti STL devono essere compilati con l'opzione del compilatore per attivare la /EHsc gestione delle eccezioni e quindi i progetti che fanno riferimento al progetto di libreria statica.

Utilizzare /translateInclude.

L'opzione /translateInclude del compilatore (disponibile nella finestra di dialogo Pagine delle proprietà del progetto in C/C++>General>Translate Includes to Imports) semplifica l'uso di una libreria di unità di intestazione nei progetti meno recenti delle #include librerie STL. Non è necessario modificare #include le direttive in import nel progetto, pur offrendo il vantaggio di importare le unità di intestazione anziché includerle.

Ad esempio, se nel progetto si fa #include <vector> riferimento a una libreria statica che contiene un'unità di intestazione per <vector>, non è necessario passare #include <vector> manualmente a import <vector>; nel codice sorgente. Al contrario, il compilatore considera #include <vector> automaticamente come import <vector>;. Per altre informazioni dettagliate su questo approccio, vedere Approccio 2: Analisi include le intestazioni STL da importare. Non tutti i file di intestazione STL possono essere compilati in un'unità di intestazione. Fornito header-units.json con Visual Studio elenca i file di intestazione STL che possono essere compilati in unità di intestazione. Un'intestazione che si basa su macro per specificarne il comportamento spesso non può essere compilata in un'unità di intestazione.

Un'istruzione #include che non fa riferimento a un'unità di intestazione viene considerata come normale #include.

Riutilizzare le unità di intestazione tra i progetti

Le unità di intestazione compilate da un progetto di libreria statica sono automaticamente disponibili per tutti i progetti direttamente e indirettamente che fanno riferimento. Sono disponibili impostazioni di progetto che consentono di selezionare le unità di intestazione che devono essere automaticamente disponibili per tutti i progetti di riferimento. Le impostazioni si trovano nelle impostazioni del progetto in Directory VC++.

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto e scegliere Proprietà per aprire la finestra di dialogo Pagine delle proprietà del progetto.
  2. Nel riquadro sinistro della finestra di dialogo selezionare Proprietà>di configurazione Directory VC++:Screenshot che mostra le proprietà del contenuto del progetto pubblico, ad esempio Directory di inclusione pubbliche e Tutti i file di intestazione sono Pubblici.

Le proprietà seguenti controllano la visibilità delle unità di intestazione nel sistema di compilazione:

  • Le directory di inclusione pubbliche specificano le directory di progetto per le unità di intestazione che devono essere aggiunte automaticamente al percorso di inclusione nei progetti di riferimento.
  • Le directory dei moduli C++ pubbliche specificano le directory di progetto che contengono unità di intestazione che devono essere disponibili per fare riferimento ai progetti. Questa proprietà consente di rendere pubbliche alcune unità di intestazione. È visibile ad altri progetti, quindi inserisci le unità di intestazione che vuoi condividere qui. Se si usa questa impostazione, per praticità, specificare directory di inclusione pubbliche per aggiungere automaticamente le intestazioni pubbliche al percorso Includi nei progetti di riferimento.
  • Tutti i moduli sono Pubblici: quando si usano unità di intestazione compilate come parte di un progetto DLL, i simboli devono essere esportati dalla DLL. Per esportare automaticamente i simboli del modulo, impostare questa proprietà su .

Usare un file di modulo predefinito

In genere, il modo più semplice per riutilizzare le unità di intestazione tra le soluzioni consiste nel fare riferimento a un progetto di unità di intestazione condivisa da ogni soluzione.

Se è necessario usare un'unità di intestazione compilata per cui non si dispone del progetto, è possibile specificare dove si trova il file compilato .ifc in modo da poterlo importare nella soluzione. Per accedere a questa impostazione:

  1. Nel menu principale selezionare Proprietà progetto>per aprire la finestra di dialogo Pagine delle proprietà del progetto.
  2. Nel riquadro sinistro della finestra di dialogo selezionare Proprietà>di configurazione C/C++>Generale.
  3. In Dipendenze modulo aggiuntive aggiungere i moduli a cui fare riferimento, separati da punti e virgola. Di seguito è riportato un esempio del formato da usare per dipendenze aggiuntive del modulo: ModuleName1=Path\To\ModuleName1.ifc; ModuleName2=Path\To\ModuleName2.ifcScreenshot che mostra le proprietà delle pagine delle proprietà del progetto in Proprietà di configurazione, C/C++, Generale, con dipendenze aggiuntive del modulo selezionate.

Selezionare tra più copie di un'unità di intestazione

Se si fa riferimento a progetti che compilano più unità di intestazione, con lo stesso nome o per lo stesso file di intestazione, è necessario specificarne uno da usare. È possibile che siano presenti versioni diverse dell'unità di intestazione compilate con impostazioni del compilatore diverse, ad esempio e che sia necessario specificare quella corrispondente alle impostazioni del progetto.

Utilizzare la proprietà Dipendenze unità di intestazione aggiuntive del progetto per risolvere i conflitti specificando l'unità di intestazione da usare. In caso contrario, non è possibile stimare quale sia selezionata.

Per impostare la proprietà Dipendenze unità intestazione aggiuntive :

  1. Nel menu principale selezionare Proprietà progetto>per aprire la finestra di dialogo Pagine delle proprietà del progetto.
  2. Nel riquadro sinistro della finestra di dialogo selezionare Proprietà>di configurazione C/C++>Generale.
  3. Specificare i moduli o i file di unità di intestazione da usare in Dipendenze aggiuntive dell'unità di intestazione per risolvere i conflitti. Usare questo formato per dipendenze aggiuntive dell'unità di intestazione: Path\To\Header1.h= Path\To\HeaderUnit1.ifc;Path\To\Header2.h= Path\To\ HeaderUnit2.ifcScreenshot che mostra l'impostazione Dipendenze unità intestazione aggiuntive nella finestra di dialogo Pagine delle proprietà del progetto.

Importante

Assicurarsi che i progetti che condividono le unità di intestazione vengano compilati con opzioni di compilazione compatibili. Se si usano le opzioni di compilazione quando si implementa l'unità di intestazione diversa da quelle usate al momento della creazione, il compilatore genererà avvisi.

Nota

Per usare le unità di intestazione compilate come parte di un progetto DLL, impostare Tutti i moduli su Pubblico su .

Approccio 2: l'analisi include la ricerca di intestazioni STL da importare

Un altro modo per importare le librerie STL consiste nel fare in modo che Visual Studio analizzi le intestazioni #include STL nel progetto e le compili in unità di intestazione. Il compilatore importa quindi anziché includere tali intestazioni.

Questa opzione è utile quando il progetto include molti file di intestazione STL in molti file o quando la velocità effettiva della compilazione non è critica. Questa opzione non garantisce che un'unità di intestazione per un file di intestazione specifico venga compilata una sola volta. Tuttavia, è utile se si dispone di una codebase di grandi dimensioni: non è necessario modificare il codice sorgente per sfruttare i vantaggi delle unità di intestazione per molte delle librerie STL usate.

Questo approccio è meno flessibile rispetto all'approccio alla libreria statica, perché non si presta a riutilizzare le unità di intestazione compilate in altri progetti. Questo approccio potrebbe non essere appropriato per progetti di grandi dimensioni: non garantisce un tempo di compilazione ottimale, perché tutte le origini devono essere analizzate per #include le istruzioni.

Non tutti i file di intestazione possono essere convertiti automaticamente in unità di intestazione. Ad esempio, le intestazioni che dipendono dalla compilazione condizionale tramite macro non devono essere convertite in unità di intestazione. Esiste un elenco di elementi consentiti sotto forma di header-units.json file per le intestazioni STL usate dal compilatore quando /translateInclude viene specificato. Determina quali intestazioni STL possono essere compilate in unità di intestazione. Il header-units.json file si trova nella directory di installazione per Visual Studio. Ad esempio: %ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json. Se il file di intestazione STL non è presente nell'elenco, viene considerato come normale #include anziché importarlo come unità di intestazione. Un altro vantaggio del header-units.json file è che impedisce la duplicazione dei simboli nelle unità di intestazione compilate. Ciò significa che, se la compilazione di un'unità di intestazione inserisce più volte un'altra intestazione della libreria, i simboli non verranno duplicati.

Per provare questo approccio, creare un progetto che includa due librerie STL. Modificare quindi le proprietà del progetto in modo da importare le librerie come unità di intestazione anziché includerle, come descritto nella sezione successiva.

Creare un progetto di app console C++

Seguire questa procedura per creare un progetto che include due librerie STL: <iostream> e <vector>.

  1. In Visual Studio creare un nuovo progetto di app console C++.

  2. Sostituire il contenuto del file di origine come indicato di seguito:

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

Impostare le opzioni del progetto ed eseguire il progetto

I passaggi seguenti impostano l'opzione che fa sì che il compilatore analizzi le intestazioni incluse da convertire in unità di intestazione. Impostano anche l'opzione che fa sì che il compilatore consideri #include come se fosse stato scritto import per i file di intestazione che possono essere considerati unità di intestazione.

  1. Nel menu principale selezionare Proprietà progetto>per aprire la finestra di dialogo Pagine delle proprietà del progetto.
  2. Selezionare Tutte le configurazioni nell'elenco a discesa Configurazione e quindi selezionare Tutte le piattaforme nell'elenco a discesa Piattaforma . Queste impostazioni assicurano che le modifiche vengano applicate indipendentemente dal fatto che si stia compilando per il debug o la versione e altre configurazioni.
  3. Nel riquadro sinistro della finestra di dialogo selezionare Proprietà>di configurazione C/C++>Generale.
  4. Impostare Origini di analisi per le dipendenze del modulo su . Questa impostazione garantisce che tutti i file di intestazione compatibili siano compilati in unità di intestazione.
  5. Impostare Traduci include su Importazioni su . Questa impostazione compila i file di intestazione STL elencati nel header-unit.json file come unità di intestazione e quindi li importa anziché usare il preprocessore.#include Screenshot che mostra l'impostazione della proprietà delle dipendenze del modulo di analisi nelle pagine delle proprietà del progetto.
  6. Scegliere OK per salvare le modifiche e chiudere la finestra di dialogo Pagine delle proprietà del progetto.

L'opzione /std:c++20 o versione successiva è necessaria per usare le unità di intestazione. Per modificare lo standard del linguaggio C++ usato dal compilatore:

  1. Nel menu principale selezionare Proprietà progetto>per aprire la finestra di dialogo Pagine delle proprietà del progetto.
  2. Selezionare Tutte le configurazioni nell'elenco a discesa Configurazione e quindi selezionare Tutte le piattaforme nell'elenco a discesa Piattaforma . Queste impostazioni assicurano che le modifiche vengano applicate indipendentemente dal fatto che si stia compilando per il debug o la versione e altre configurazioni.
  3. Nel riquadro sinistro della finestra di dialogo Pagine delle proprietà del progetto selezionare Proprietà>di configurazione Generale.
  4. Nell'elenco a discesa Standard del linguaggio C++ selezionare ISO C++20 Standard (/std:c++20) (o versione successiva).
  5. Scegliere OK per salvare le modifiche e chiudere la finestra di dialogo Pagine delle proprietà del progetto.
  6. Dal menu principale compilare la soluzione selezionando Compila>soluzione.

Eseguire la soluzione per verificare che produa l'output previsto: 1

La considerazione principale per determinare se usare questo approccio è l'equilibrio tra praticità e costo di analisi di tutti i file per determinare quali file di intestazione compilare come unità di intestazione.

Vedi anche

Confrontare unità di intestazione, moduli e intestazioni precompilate
Esercitazione: Importare la libreria standard C++ usando i moduli
Procedura dettagliata: Compilare e importare unità di intestazione nei progetti Visual C++
/translateInclude