Powiedz, że mam poniższy (bardzo prosty) kod.
#include <iostream>
int main() {
std::cout << std::stoi("12");
}
Kompiluje to dobrze zarówno na g ++, jak i clang; jednak nie można go skompilować na MSVC z następującym błędem:
błąd C2039: „stoi”: nie jest członkiem „std”
błąd C3861: „stoi”: nie znaleziono identyfikatora
Wiem, że std::stoi
jest to część <string>
nagłówka, który prawdopodobnie obejmuje dwa poprzednie kompilatory, <iostream>
a drugi nie. Zgodnie ze standardem C ++ [res.on.headers]
Nagłówek C ++ może zawierać inne nagłówki C ++.
Co dla mnie w zasadzie mówi, że wszystkie trzy kompilatory są poprawne.
Kwestia ta pojawiła się, gdy jeden z moich studentów przesłał prace, które TA oznaczyła jako niekompilujące; Oczywiście poszedłem i to naprawiłem. Chciałbym jednak zapobiec takim incydentom w przyszłości. Czy istnieje sposób na określenie, które pliki nagłówkowe powinny zostać uwzględnione, bez kompilacji na trzech różnych kompilatorach, które należy sprawdzać za każdym razem?
Jedynym sposobem, jaki mogę wymyślić, jest zapewnienie, aby dla każdego std
wywołania funkcji istniało odpowiednie uwzględnienie; ale jeśli masz istniejący kod, który ma tysiące linii, przeszukiwanie go może być uciążliwe. Czy istnieje łatwiejszy / lepszy sposób zapewnienia zgodności między kompilatorami?
Przykład z trzema kompilatorami: https://godbolt.org/z/kJhS6U
std::stoi
jest to do obsługi ciągów, możesz zgadywać, że<string>
byłby to dobry nagłówek do włączenia. Lub możesz wyszukać dobre referencje, które ci powiedzą. I zalecam, aby zawsze jawnie dołączać pliki nagłówkowe, abyś nie musiał polegać na nieprzenośnych specyficznych zachowaniach związanych z implementacją.std::stoi
natychmiast upewniasz się, że również#include <string>
jest obecny.Odpowiedzi:
To zawsze będzie trochę uciążliwe, jeśli masz ogromną bazę kodu i do tej pory tego nie robiłeś, ale kiedy już skończysz poprawianie załączników, możesz zastosować się do prostej procedury:
Kiedy piszesz nowy kod, który używa standardowej funkcji, takiej jak
std::stoi
Podłącz tę nazwę do Google, przejdź do artykułu cppreference.com, a następnie spójrz na górę, aby zobaczyć, w którym nagłówku jest zdefiniowany.Następnie dołącz to, jeśli jeszcze nie zostało uwzględnione. Zadanie wykonane!
(Możesz do tego użyć standardu, ale nie jest to tak łatwo dostępne).
Nie ulegaj pokusie, aby pozbyć się wszystkiego na rzecz tanich, niemożliwych do przenoszenia hacków takich jak
<bits/stdc++.h>
!tl; dr: dokumentacja
źródło
Oprócz przeglądania dokumentacji i robienia tego ręcznie (bolesne i czasochłonne) możesz skorzystać z niektórych narzędzi, które mogą to zrobić za Ciebie.
Możesz użyć ReSharper w Visual Studio, który jest w stanie organizować import (w rzeczywistości VS bez ReSharper nie jest zbyt użyteczny). W przypadku braku dołączenia zaleca się jego dodanie, a jeśli jest przestarzała, linia z włączeniem jest wyświetlana w bardziej jasnych kolorach.
Lub możesz użyć CLion (dostępny na wszystkie platformy), który również ma tę funkcję (w rzeczywistości jest to ta sama produkcja JetBrains).
Istnieje również narzędzie o nazwie włącz to, czego użyłeś , ale jego celem jest skorzystanie z deklaracji forward, nigdy tego nie użyłem (osobiście - mój kolega z zespołu zrobił to dla naszego projektu).
źródło