Digamos que eu tenho o código abaixo (muito simples).
#include <iostream>
int main() {
std::cout << std::stoi("12");
}
Isso compila bem no g ++ e no clang; no entanto, ele falha ao compilar no MSVC com o seguinte erro:
erro C2039: 'stoi': não é membro de 'std'
erro C3861: 'stoi': identificador não encontrado
Eu sei que isso std::stoi
faz parte do <string>
cabeçalho, o que provavelmente os dois ex-compiladores incluem como parte <iostream>
e o último não. De acordo com o padrão C ++ [res.on.headers]
Um cabeçalho C ++ pode incluir outros cabeçalhos C ++.
O que, para mim, basicamente diz que todos os três compiladores estão corretos.
Esse problema surgiu quando um dos meus alunos enviou um trabalho que o AT marcou como não compilando; Claro que fui e consertei. No entanto, gostaria de evitar futuros incidentes como esse. Portanto, existe uma maneira de determinar quais arquivos de cabeçalho devem ser incluídos, com exceção da compilação em três compiladores diferentes para verificar sempre?
A única maneira de pensar é garantir que, para cada std
chamada de função, exista uma inclusão apropriada; mas se você tiver um código existente com milhares de linhas, pode ser entediante pesquisar. Existe uma maneira mais fácil / melhor de garantir a compatibilidade entre compiladores?
Exemplo com os três compiladores: https://godbolt.org/z/kJhS6U
std::stoi
é para lidar com seqüências de caracteres, você pode adivinhar que<string>
seria um bom cabeçalho para incluir. Ou você pode procurar uma boa referência que lhe dirá. E eu recomendo que você sempre inclua explicitamente os arquivos de cabeçalho, para que não precise confiar no comportamento específico da implementação não portátil.std::stoi
, você imediatamente se certifica de que também#include <string>
está presente.Respostas:
Isso sempre será um pouco complicado se você tiver uma base de código enorme e ainda não o fez até agora, mas depois de corrigir suas inclusões, você pode seguir um procedimento simples:
Quando você escreve um novo código que usa um recurso padrão
std::stoi
, conecte esse nome ao Google, vá para o artigo cppreference.com e veja o topo para ver em qual cabeçalho está definido.Em seguida, inclua isso, se ainda não estiver incluído. Tarefa concluída!
(Você pode usar o padrão para isso, mas não é tão acessível.)
Não fique tentado a demitir tudo em favor de hacks baratos e não portáveis como
<bits/stdc++.h>
!tl; dr: documentação
fonte
Além de revisar a documentação e fazer isso manualmente (doloroso e demorado), você pode usar algumas ferramentas que podem fazer isso por você.
Você pode usar o ReSharper no Visual Studio, capaz de organizar importações (na verdade, o VS sem o ReSharper não é muito utilizável). Se o include estiver ausente, recomenda-se adicioná-lo e se for obsoleto, a linha com o include é mostrada em cores mais claras.
Ou você pode usar o CLion (disponível para todas as plataformas) que também possui esse recurso (na verdade, esse é o mesmo JetBrains de fabricação).
Também existe uma ferramenta chamada include, o que você usou , mas seu objetivo é aproveitar as vantagens da declaração direta, nunca usei isso (pessoalmente - meu companheiro de equipe fez isso no nosso projeto).
fonte