Digamos que tengo el siguiente código (muy simple).
#include <iostream>
int main() {
std::cout << std::stoi("12");
}
Esto compila bien tanto en g ++ como en clang; sin embargo, no se compila en MSVC con el siguiente error:
error C2039: 'stoi': no es miembro de 'std'
error C3861: 'stoi': identificador no encontrado
Sé que std::stoi
es parte del <string>
encabezado, que presumiblemente los dos compiladores anteriores incluyen como parte <iostream>
y el último no. De acuerdo con el estándar C ++ [res.on.headers]
Un encabezado de C ++ puede incluir otros encabezados de C ++.
Lo cual, para mí, básicamente dice que los tres compiladores son correctos.
Este problema surgió cuando uno de mis alumnos presentó trabajo, que el TA marcó como no compilado; Por supuesto, fui y lo arreglé. Sin embargo, me gustaría evitar futuros incidentes como este. Entonces, ¿hay alguna manera de determinar qué archivos de encabezado deben incluirse, a menos que se compile en tres compiladores diferentes para verificar cada vez?
La única forma en que puedo pensar es asegurar que para cada std
llamada a la función, exista una inclusión apropiada; pero si tiene un código existente que tiene miles de líneas, puede ser tedioso buscarlo. ¿Existe una forma más fácil / mejor de garantizar la compatibilidad entre compiladores?
Ejemplo con los tres compiladores: https://godbolt.org/z/kJhS6U
std::stoi
es para manejar cadenas , podría adivinar que<string>
sería un buen encabezado para incluir. O puede buscar una buena referencia que le dirá. Y le recomiendo que siempre incluya explícitamente los archivos de encabezado, para que no tenga que confiar en un comportamiento específico de implementación no portátil.std::stoi
inmediatamente se asegura de que#include <string>
esté presente también.Respuestas:
Esto siempre será una tarea difícil si tienes una gran base de código y no has estado haciendo esto hasta ahora, pero una vez que hayas arreglado tus inclusiones, puedes seguir un procedimiento simple:
Cuando escriba un código nuevo que use una característica estándar, como
std::stoi
, conecte ese nombre a Google, vaya al artículo de cppreference.com y luego mire la parte superior para ver en qué encabezado está definido.Luego, inclúyalo si aún no está incluido. ¡Trabajo hecho!
( Podría usar el estándar para esto, pero no es tan accesible).
¡No caigas en la tentación de despedirlo todo a favor de trucos baratos e inportables como
<bits/stdc++.h>
!tl; dr: documentación
fuente
Además de revisar la documentación y hacerlo manualmente (doloroso y lento), puede usar algunas herramientas que pueden hacerlo por usted.
Puede usar ReSharper en Visual Studio, que es capaz de organizar las importaciones (de hecho, VS sin ReSharper no es muy útil). Si falta incluir, recomienda agregarlo y si está obsoleto, la línea con inclusión se muestra en colores más pálidos.
O puede usar CLion (disponible para todas las plataformas) que también tiene esta capacidad (de hecho, este es el mismo fabricante de JetBrains).
También hay una herramienta llamada incluir lo que usó , pero su objetivo es aprovechar las ventajas de la declaración hacia adelante, nunca usé eso (personalmente, mi compañero de equipo lo hizo para nuestro proyecto).
fuente