Partilhar via


Passo a passo: Importar bibliotecas STL como unidades de cabeçalho

Este passo a passo mostra como importar bibliotecas STL (C++ Standard Template Library) como unidades de cabeçalho no Visual Studio. Para obter uma maneira ainda mais rápida e robusta de importar a biblioteca padrão, consulte Tutorial: Importar a biblioteca padrão C++ usando módulos.

Importar um cabeçalho STL como uma unidade de cabeçalho é mais simples do que usar arquivos de cabeçalho pré-compilados. As unidades de cabeçalho são mais fáceis de configurar e usar, são substancialmente menores no disco, oferecem benefícios de desempenho semelhantes e são mais flexíveis do que uma PCH compartilhada.

Para obter informações mais detalhadas sobre o que são unidades de cabeçalho e os benefícios que elas oferecem, consulte O que é uma unidade de cabeçalho?. Para contrastar unidades de cabeçalho com outras maneiras de importar a biblioteca padrão, consulte Comparar unidades de cabeçalho, módulos e cabeçalhos pré-compilados.

Pré-requisitos

Para usar unidades de cabeçalho, use o Visual Studio 2022 ou posterior ou o Visual Studio 2019 versão 16.11 ou posterior. A opção /std:c++20 (ou posterior) é necessária para usar unidades de cabeçalho.

Duas abordagens para importar cabeçalhos STL como unidades de cabeçalho

Antes de importar um cabeçalho STL, ele deve ser compilado em uma unidade de cabeçalho. Uma unidade de cabeçalho é uma representação binária de um arquivo de cabeçalho. Possui uma extensão .ifc.

A abordagem recomendada é criar uma biblioteca estática que contenha as unidades de cabeçalho construídas para os cabeçalhos STL que você deseja usar. Em seguida, faça referência a essa biblioteca e às suas unidades de cabeçalho. Essa abordagem pode resultar em compilações mais rápidas e melhor reutilização. Para experimentar essa abordagem, consulte Abordagem 1: Criar uma biblioteca estática de unidades de cabeçalho de biblioteca STL.

Outra abordagem é fazer com que o Visual Studio procure os cabeçalhos STL que você #include no seu projeto, compile-os em unidades de cabeçalho e import em vez de #include esses cabeçalhos. Essa abordagem é útil se você tiver uma base de código grande, porque você não precisa alterar seu código-fonte. Essa abordagem é menos flexível do que a abordagem de biblioteca estática, porque não se presta a reutilizar as unidades de cabeçalho construídas em outros projetos. Mas, você ainda obtém a vantagem de desempenho de importar bibliotecas STL individuais como unidades de cabeçalho. Para experimentar essa abordagem, consulte Abordagem 2: Inclui varredura para importar cabeçalhos STL.

Abordagem 1: Criar uma biblioteca estática de unidades de cabeçalho de biblioteca STL

A maneira recomendada de consumir bibliotecas STL como unidades de cabeçalho é criar um ou mais projetos de biblioteca estática. Esses projetos devem consistir nas unidades de cabeçalho da biblioteca STL que você deseja usar. Em seguida, faça referência aos projetos de biblioteca para consumir essas unidades de cabeçalho STL. É semelhante ao uso de cabeçalhos pré-compilados compartilhados, mas mais fácil.

As unidades de cabeçalho (e módulos) construídas em um projeto de biblioteca estática estão automaticamente disponíveis para projetos de referência porque o sistema de projeto adiciona automaticamente a opção de linha de comando apropriada /headerUnit ao compilador para que os projetos de referência possam importar as unidades de cabeçalho.

Essa abordagem garante que a unidade de cabeçalho para um cabeçalho específico seja criada apenas uma vez. Ele permite que você importe algumas ou todas as unidades de cabeçalho, o que não é possível com uma PCH. Você pode incluir unidades de cabeçalho em qualquer ordem.

No exemplo a seguir, você cria um projeto de biblioteca estática que consiste nas <iostream> unidades de cabeçalho e <vector> . Depois que a solução for criada, você fará referência a esse projeto de unidade de cabeçalho compartilhado de outro projeto C++. Sempre que se encontrar import <iostream>; ou import <vector>;, a unidade de cabeçalho construída para essa biblioteca é usada em vez de traduzir o cabeçalho com o pré-processador. Ele melhora o desempenho da compilação, como os arquivos PCH, quando o mesmo cabeçalho é incluído em vários arquivos. O cabeçalho não terá de ser processado repetidamente pelos ficheiros que o incluem. Em vez disso, a unidade de cabeçalho compilada já processada é importada.

Para criar uma biblioteca estática que contenha as bibliotecas <iostream> STL e <vector>, siga estes passos:

  1. Crie um projeto C++ vazio. Nomeie-o SharedPrj.
    Selecione Projeto vazio para C++ nos tipos de projeto disponíveis na janela Criar um novo projeto : captura de tela que mostra a criação de um novo projeto C++ vazio.

  2. Adicione um novo arquivo C++ ao projeto. Altere o conteúdo do ficheiro para:

    import <iostream>;
    import <vector>;
    

Definir propriedades do projeto

Defina as propriedades do projeto para compartilhar as unidades de cabeçalho deste projeto:

  1. No menu principal do Visual Studio, selecione Projeto>Propriedades SharedPrj para abrir a caixa de diálogo das Propriedades do Projeto: Captura de tela que mostra as configurações para Tipo de Configuração e Padrão de Linguagem C++.
  2. Selecione Todas as configurações na lista suspensa Configuração e, em seguida, selecione Todas as plataformas na lista suspensa Plataforma . Essas configurações garantem que as suas alterações se apliquem independentemente de você estar criando para depuração ou versão final.
  3. No painel esquerdo da caixa de diálogo Páginas de propriedades do projeto, selecione Propriedades>gerais de configuração.
  4. Altere a opção Tipo de configuração para Biblioteca estática (.lib).
  5. Altere o padrão de linguagem C++ para o padrão ISO C++20 (/std:c++20) (ou posterior).
  6. No painel esquerdo da caixa de diálogo Páginas de propriedades do projeto, selecione Propriedades> de configuraçãoC/C++>General.
  7. Na lista suspensa Analisar fontes para dependências de módulo, selecione Sim. (Esta opção faz com que o compilador analise seu código em busca de dependências que podem ser incorporadas em unidades de cabeçalho): Captura de tela que mostra a configuração da propriedade de dependências do módulo de verificação.
  8. Escolha OK para fechar a caixa de diálogo Páginas de propriedades do projeto. Crie a solução selecionando Build>Build Solution no menu principal.

Fazer referência à biblioteca de unidades de cabeçalho

Para importar <iostream> e <vector> como unidades de cabeçalho da biblioteca estática, crie um projeto que faça referência à biblioteca estática da seguinte maneira:

  1. Com a solução atual ainda aberta, no menu Visual Studio, selecione Arquivo>Adicionar>Novo Projeto.

  2. No assistente Criar um novo projeto , selecione o modelo Aplicativo de Console C++ e escolha Avançar.

  3. Nomeie o novo projeto como Passo a passo. Altere a lista suspensa Solução para Adicionar à solução. Escolha Criar para criar o projeto e adicioná-lo à sua solução.

  4. Altere o conteúdo do arquivo de origem do Walkthrough.cpp da seguinte maneira:

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

As unidades de cabeçalho requerem a opção /std:c++20 (ou posterior). Defina o padrão de idioma usando as seguintes etapas:

  1. No Gerenciador de Soluções, clique com o botão direito do mouse no projeto Passo a passo e selecione Propriedades para abrir a caixa de diálogo Páginas de Propriedades do projeto: Captura de tela que mostra a configuração do padrão de idioma para a versão de visualização.
  2. No painel esquerdo da caixa de diálogo Páginas de Propriedades do projeto Walkthrough, selecione Propriedades de Configuração>Geral.
  3. No menu suspenso Padrão de linguagem C++ , selecione ISO C++20 Standard (/std:c++20) (ou posterior).
  4. Escolha OK para fechar a caixa de diálogo Páginas de propriedades do projeto.

No projeto Passo a passo , adicione uma referência ao projeto SharedPrj com as seguintes etapas:

  1. No projeto Passo a passo , selecione o nó Referências e, em seguida, selecione Adicionar Referência. Selecione SharedPrj na lista de projetos: Captura de tela que mostra a caixa de diálogo Adicionar referência. Ele é usado para adicionar uma referência ao projeto Passo a passo. Adicionar essa referência faz com que o sistema de compilação use as unidades de cabeçalho criadas por SharedPrj sempre que um import no projeto Passo a passo corresponder a uma das unidades de cabeçalho construídas em SharedPrj.
  2. Escolha OK para fechar a caixa de diálogo Adicionar referência .
  3. Clique com o botão direito do mouse no projeto Passo a passo e selecione Definir como projeto de inicialização.
  4. Crie a solução. (Use Build>Criar solução no menu principal.) Execute-o para ver se ele produz a saída esperada: 1

A vantagem dessa abordagem é que você pode fazer referência ao projeto de biblioteca estática de qualquer projeto para reutilizar as unidades de cabeçalho nele. Neste exemplo, a biblioteca estática contém as <vector> unidades de cabeçalho e <iostream> .

Você pode criar um projeto de biblioteca estática monolítica que contenha todos os cabeçalhos STL comumente usados que você deseja importar de seus vários projetos. Ou você pode criar projetos de biblioteca compartilhada menores para os diferentes agrupamentos de bibliotecas STL que deseja importar como unidades de cabeçalho. Em seguida, faça referência a esses projetos de unidade de cabeçalho compartilhados, conforme necessário.

O resultado deve ser uma maior eficiência de compilação porque a importação de uma unidade de cabeçalho reduz significativamente o esforço necessário do compilador.

Quando você usa essa abordagem com seus próprios projetos, crie o projeto de biblioteca estática com opções de compilador que são compatíveis com o projeto que faz referência a ele. Por exemplo, os projetos STL devem ser criados com a opção do compilador para ativar o /EHsc tratamento de exceções, assim como os projetos que fazem referência ao projeto de biblioteca estática.

Utilize /translateInclude

A /translateInclude opção de compilador (disponível na caixa de diálogo Páginas de propriedades do projeto em C/C++>General>Translate Includes to Imports) facilita o uso de uma biblioteca de unidades de cabeçalho em projetos mais antigos que #include as bibliotecas STL. Isso torna desnecessário alterar #include diretivas para import no seu projeto, enquanto ainda lhe dá a vantagem de importar as unidades de cabeçalho em vez de incluí-las.

Por exemplo, se você tiver #include <vector> em seu projeto e fizer referência a uma biblioteca estática que contenha uma unidade de cabeçalho para <vector>, não será necessário alterar #include <vector> manualmente para import <vector>; no código-fonte. Em vez disso, o compilador trata #include <vector> automaticamente como import <vector>;. Para obter mais informações em detalhes sobre essa abordagem, consulte Abordagem 2: Inclui varredura para cabeçalhos STL a serem importados. Nem todos os arquivos de cabeçalho STL podem ser compilados em uma unidade de cabeçalho. O Visual Studio header-units.json inclui uma lista dos ficheiros de cabeçalho STL que podem ser compilados em unidades de cabeçalho. Um cabeçalho que depende de macros para especificar seu comportamento muitas vezes não pode ser compilado em uma unidade de cabeçalho.

Uma #include instrução que não se refere a uma unidade de cabeçalho é tratada como uma normal #include.

Reutilizar unidades de cabeçalho entre projetos

As unidades de cabeçalho construídas por um projeto de biblioteca estática estão automaticamente disponíveis para todos os projetos de referência direta e indireta. Há configurações de projeto que permitem selecionar quais unidades de cabeçalho devem estar automaticamente disponíveis para todos os projetos de referência. As configurações estão nas configurações do projeto em Diretórios VC++.

  1. No Gerenciador de Soluções, clique com o botão direito do mouse no projeto e selecione Propriedades para abrir a caixa de diálogo Páginas de Propriedades do projeto.
  2. No painel esquerdo da caixa de diálogo, selecione Propriedades de Configuração>Diretórios VC++: captura de ecrã que demonstra as propriedades de conteúdo do projeto público, como Diretórios de Inclusão Públicos e Todos os Ficheiros de Cabeçalho são Públicos.

As propriedades a seguir controlam a visibilidade das unidades de cabeçalho para o sistema de compilação:

  • Public Include Directories especifica diretórios de projeto para unidades de cabeçalho que devem ser adicionados automaticamente ao caminho de inclusão em projetos de referência.
  • Public C++ Module Directories especifica quais diretórios de projeto contêm unidades de cabeçalho que devem estar disponíveis para projetos de referência. Esta propriedade permite que você torne algumas unidades de cabeçalho públicas. É visível para outros projetos, então coloque unidades de cabeçalho que você deseja compartilhar aqui. Se utilizar esta configuração, para conveniência, especifique Diretórios de Inclusão Pública para adicionar automaticamente os seus cabeçalhos públicos ao Include path nos projetos de referência.
  • Todos os módulos são públicos: quando você usa unidades de cabeçalho construídas como parte de um projeto DLL, os símbolos devem ser exportados da DLL. Para exportar símbolos de módulo automaticamente, defina esta propriedade como Sim.

Usar um arquivo de módulo pré-construído

Normalmente, a maneira mais fácil de reutilizar unidades de cabeçalho entre soluções é fazer referência a um projeto de unidade de cabeçalho compartilhado de cada solução.

Se você precisar usar uma unidade de cabeçalho construída para a qual não tenha o projeto, poderá especificar onde o arquivo construído .ifc está para poder importá-lo em sua solução. Para acessar essa configuração:

  1. No menu principal, selecionePropriedades do > para abrir a caixa de diálogo Páginas de propriedades do projeto.
  2. No painel esquerdo da caixa de diálogo, selecione Propriedades> de configuraçãoC/C++>General.
  3. Em Dependências de módulo adicionais, adicione os módulos à referência, separados por ponto-e-vírgula. Aqui está um exemplo do formato a ser usado para Dependências de Módulo Adicionais: ModuleName1=Path\To\ModuleName1.ifc; ModuleName2=Path\To\ModuleName2.ifcCaptura de tela mostrando as propriedades das Páginas de Propriedades do projeto em Propriedades de Configuração, C/C++, Geral, com Dependências de Módulo Adicionais selecionadas.

Selecionar entre várias cópias de uma unidade de cabeçalho

Se você fizer referência a projetos que criam várias unidades de cabeçalho, com o mesmo nome ou para o mesmo arquivo de cabeçalho, deverá especificar qual usar. Você pode ter diferentes versões da unidade de cabeçalho criadas com diferentes configurações do compilador, por exemplo, e deve especificar a que corresponde às configurações do projeto.

Use a propriedade Additional Header Unit Dependencies do projeto para resolver colisões especificando qual unidade de cabeçalho usar. Caso contrário, não é possível prever qual deles será escolhido.

Para definir a propriedade Dependências da Unidade de Cabeçalho Adicional :

  1. No menu principal, selecionePropriedades do > para abrir a caixa de diálogo Páginas de propriedades do projeto.
  2. No painel esquerdo da caixa de diálogo, selecione Propriedades> de configuraçãoC/C++>General.
  3. Especifique quais módulos ou arquivos de unidade de cabeçalho usar em dependências adicionais de unidade de cabeçalho para resolver colisões. Use este formato para Dependências Adicionais de Unidade de Cabeçalho: Path\To\Header1.h= Path\To\HeaderUnit1.ifc;Path\To\Header2.h= Path\To\ HeaderUnit2.ifcCaptura de ecrã que mostra a configuração de Dependências Adicionais de Unidade de Cabeçalho na caixa de diálogo das Páginas de Propriedades do Projeto.

Importante

Certifique-se de que os projetos que compartilham unidades de cabeçalho sejam criados com opções de compilação compatíveis. Se você usar opções de compilação ao implementar a unidade de cabeçalho que são diferentes das que você usou quando a criou, o compilador emitirá avisos.

Observação

Para usar unidades de cabeçalho criadas como parte de um projeto DLL, defina Todos os módulos são públicos como Sim.

Abordagem 2: A verificação inclui cabeçalhos STL para importar

Outra maneira de importar bibliotecas STL é fazer com que o Visual Studio verifique os cabeçalhos #include STL em seu projeto e compile-os em unidades de cabeçalho. Em seguida, o compilador importa em vez de incluir esses cabeçalhos.

Essa opção é conveniente quando seu projeto inclui muitos arquivos de cabeçalho STL em muitos arquivos ou quando a taxa de transferência de compilação não é crítica. Esta opção não garante que uma unidade de cabeçalho para um determinado arquivo de cabeçalho seja criada apenas uma vez. No entanto, é útil se você tiver uma base de código grande: você não precisa alterar seu código-fonte para aproveitar os benefícios das unidades de cabeçalho para muitas das bibliotecas STL que você usa.

Essa abordagem é menos flexível do que a abordagem de biblioteca estática, porque não se presta a reutilizar as unidades de cabeçalho construídas em outros projetos. Essa abordagem pode não ser apropriada para projetos maiores: ela não garante um tempo de construção ideal, já que todas as fontes devem ser verificadas em busca #include de declarações.

Nem todos os arquivos de cabeçalho podem ser convertidos automaticamente em unidades de cabeçalho. Por exemplo, cabeçalhos que dependem de compilação condicional por meio de macros não devem ser convertidos em unidades de cabeçalho. Há uma lista de permissões na forma de um header-units.json arquivo para os cabeçalhos STL que o compilador usa quando /translateInclude é especificado. Ele determina quais cabeçalhos STL podem ser compilados em unidades de cabeçalho. O header-units.json arquivo está sob o diretório de instalação do Visual Studio. Por exemplo, %ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json. Se o arquivo de cabeçalho STL não estiver na lista, ele será tratado como normal #include em vez de importá-lo como uma unidade de cabeçalho. Outra vantagem do header-units.json ficheiro é que esse evita a duplicação de símbolos nas unidades de cabeçalho construídas. Ou seja, se a compilação de uma unidade de cabeçalho trouxer outro cabeçalho de biblioteca várias vezes, os símbolos não serão duplicados.

Para experimentar essa abordagem, crie um projeto que inclua duas bibliotecas STL. Em seguida, altere as propriedades do projeto para que ele importe as bibliotecas como unidades de cabeçalho em vez de incluí-las, conforme descrito na próxima seção.

Criar um projeto de aplicativo de console C++

Siga estas etapas para criar um projeto que inclua duas bibliotecas STL: <iostream> e <vector>.

  1. No Visual Studio, crie um novo projeto de aplicativo de console C++.

  2. Substitua o conteúdo do arquivo de origem da seguinte maneira:

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

Definir opções de projeto e executar o projeto

As etapas a seguir definem a opção que faz com que o compilador verifique cabeçalhos incluídos para traduzir em unidades de cabeçalho. Eles também definem a opção que faz com que o compilador trate #include como se você tivesse escrito import para arquivos de cabeçalho que podem ser tratados como unidades de cabeçalho.

  1. No menu principal, selecionePropriedades do > para abrir a caixa de diálogo Páginas de propriedades do projeto.
  2. Selecione Todas as configurações na lista suspensa Configuração e, em seguida, selecione Todas as plataformas na lista suspensa Plataforma . Essas configurações garantem que as suas alterações se apliquem, quer esteja a criar para depuração ou publicação, ou outras configurações.
  3. No painel esquerdo da caixa de diálogo, selecione Propriedades> de configuraçãoC/C++>General.
  4. Defina Scan Sources for Module Dependencies como Sim. Essa configuração garante que todos os arquivos de cabeçalho compatíveis sejam compilados em unidades de cabeçalho.
  5. Defina Translate inclui para importações como Sim. Essa configuração compila os ficheiros de cabeçalho STL listados no ficheiro header-unit.json como unidades de cabeçalho e, em seguida, importa-os, em vez de usar o pré-processador para #include eles. Captura de ecrã que mostra a configuração da propriedade de dependências do módulo de verificação nas Páginas de Propriedades do projeto.
  6. Escolha OK para salvar as alterações e fechar a caixa de diálogo Páginas de propriedades do projeto.

A opção /std:c++20 ou uma versão posterior é necessária para usar unidades de cabeçalho. Para alterar o padrão de linguagem C++ usado pelo compilador:

  1. No menu principal, selecionePropriedades do > para abrir a caixa de diálogo Páginas de propriedades do projeto.
  2. Selecione Todas as configurações na lista suspensa Configuração e, em seguida, selecione Todas as plataformas na lista suspensa Plataforma . Essas configurações garantem que as suas alterações se apliquem, quer esteja a criar para depuração ou publicação, ou outras configurações.
  3. No painel esquerdo da caixa de diálogo Páginas de propriedades do projeto, selecione Propriedades>gerais de configuração.
  4. Na lista suspensa Padrão de linguagem C++ , selecione ISO C++20 Standard (/std:c++20) (ou posterior).
  5. Escolha OK para salvar as alterações e fechar a caixa de diálogo Páginas de propriedades do projeto.
  6. No menu principal, crie a solução selecionando Build>Build Solution.

Execute a solução para verificar se ela produz a saída esperada: 1

A principal consideração para usar ou não essa abordagem é o equilíbrio entre a conveniência e o custo de varredura de todos os seus arquivos para determinar quais arquivos de cabeçalho construir como unidades de cabeçalho.

Ver também

Comparar unidades de cabeçalho, módulos e cabeçalhos pré-compilados
Tutorial: Importar a biblioteca padrão C++ usando módulos
Passo a passo: Criar e importar unidades de cabeçalho em seus projetos do Microsoft C++
/translateInclude