Скажем, у меня есть ниже (очень простой) код.
#include <iostream>
int main() {
std::cout << std::stoi("12");
}
Это прекрасно компилируется как на g ++, так и на clang; однако он не может быть скомпилирован в MSVC со следующей ошибкой:
ошибка C2039: «Stoi»: не является членом «STD»
ошибка C3861: «стои»: идентификатор не найден
Я знаю, что std::stoi
это часть <string>
заголовка, который предположительно два бывших компилятора включают как часть, <iostream>
а последний нет. Согласно стандарту C ++ [res.on.headers]
Заголовок C ++ может включать в себя другие заголовки C ++.
Что для меня в основном говорит о том, что все три компилятора верны.
Эта проблема возникла, когда один из моих студентов представил работу, которую ТА пометил как не компилируемую; Я конечно пошел и починил это. Однако я бы хотел предотвратить подобные инциденты в будущем. Итак, есть ли способ определить, какие файлы заголовков следует включить, если не учитывать компиляцию на трех разных компиляторах, которые нужно проверять каждый раз?
Единственный способ, который я могу придумать, - убедиться, что для каждого std
вызова функции существует соответствующее включение; но если у вас есть код длиной в тысячи строк, поиск по нему может быть утомительным. Есть ли более простой / лучший способ обеспечить совместимость с кросс-компилятором?
Пример с тремя компиляторами: https://godbolt.org/z/kJhS6U
std::stoi
это для обработки строк, вы можете догадаться, что<string>
это будет хороший заголовок для включения. Или вы можете найти хорошую ссылку, которая скажет вам. И я рекомендую всегда явно включать файлы заголовков, чтобы вам не приходилось полагаться на поведение, не зависящее от переносимой реализации.std::stoi
вы сразу же убедитесь, что#include <string>
он присутствует.Ответы:
Это всегда будет немного хлопотно, если у вас огромная база кода и вы до сих пор этого не делали, но как только вы исправили свои включения, вы можете придерживаться простой процедуры:
Когда вы пишете новый код, который использует стандартную функцию, например
std::stoi
, вставьте это имя в Google, перейдите к статье cppreference.com, а затем посмотрите вверху, чтобы увидеть, в каком заголовке он определен.Затем включите это, если оно еще не включено. Работа выполнена!
(Вы можете использовать стандарт для этого, но это не так доступно.)
Не поддавайтесь искушению уволить все в пользу дешевых, непортативных хаков, как
<bits/stdc++.h>
!тл; др: документация
источник
Помимо просмотра документации и выполнения этого вручную (болезненно и отнимает много времени), вы можете использовать некоторые инструменты, которые могут сделать это для вас.
Вы можете использовать ReSharper в Visual Studio, которая способна организовать импорт (на самом деле VS без ReSharper не очень удобен). Если include отсутствует, он рекомендует добавить его, а если он устарел, строка с include будет показана более светлыми цветами.
Или вы можете использовать CLion (доступен для всех платформ), который также имеет эту возможность (на самом деле это тот же производитель JetBrains).
Существует также инструмент под названием include, который вы использовали , но его цель - воспользоваться преимуществами предварительного декларирования, я никогда не использовал его (лично - мой товарищ по команде сделал это для нашего проекта).
источник