¿Por qué no hay encabezado y puede considerarse la no existencia?
-
26-10-2019 - |
Pregunta
La biblioteca estándar incluye una <iosfwd>
encabezado, que (hacia adelante) declara todas las transmisiones, incluidas cualquier typedef
s y define el char_traits
plantilla, incluidas las especializaciones.
Lamentablemente, no hay tal <stlfwd>
encabezado que (hacia adelante) declara todos los tipos de datos y funciones de STL comunes como vector
, map
, less
, sort
, etc., aún más tristemente, el código de usuario no puede agregar tales declaraciones / typedef
s para el std
espacio de nombres, según
§17.4.3.1 [lib.reserved.names] p1
:
No está definido para un programa C + + para agregar declaraciones o definiciones al espacio de nombres
std
o espacios de nombres dentro del espacio de nombresstd
a menos que se especifique lo contrario. Un programa puede agregar especializaciones de plantilla para cualquier plantilla de biblioteca estándar al espacio de nombresstd
.
Sí, eso cubre el caso de las declaraciones (hacia adelante), incluso si los tipos ya existen en la biblioteca estándar. Por supuesto, la mayoría (¿todos?) Los compiladores se comportarán perfectamente normales, incluso si se agrega tales declaraciones, pero estrictamente y el abogado del idioma que habla, es un comportamiento indefinido. Encuentro esto especialmente tedioso por typedef
ing contenedores estándar, como:
// how to forward declare map and string?
typedef std::map<std::string, std::string> Attributes;
Ahora, ¿se puede considerar esto un defecto?
Me refiero a la no existencia de un <stlfwd>
encabezado (o mejor <stdfwd>
, cubriendo <iosfwd>
también) y la prohibición de las declaraciones ya existentes en la biblioteca estándar.
Además, según esta pregunta, si uno (hacia adelante) declara el contenedor estándar, los algoritmos y los funciones / funciones exactamente como lo demanda el estándar, el código debe ser perfectamente válido (si no era para la prohibición de las declaraciones hechas por el usuario en el std
espacio de nombres), porque las implementaciones no pueden agregar ningún parámetros de plantilla ocultos/predeterminados.
Estoy preguntando esto porque estoy pensando en enviar un informe de defectos sobre esto.
Solución
¿Cuál sería el propósito de declarar hacia adelante? less
o sort
¿O realmente algún otro algoritmo? Si está pasando un algoritmo de propósito general alrededor, seguramente será un tipo de plantilla y no necesitará una declaración directa.
Eso nos deja con los tipos de contenedores. Definitivamente hay casos en los que serían útiles las declaraciones hacia adelante, pero sospecho que simplemente se decidió que, dado que cada definición de contenedor es relativamente simple (en comparación con los iostreams), sería preferible usar la inclusión completa en lugar de unau003Ccontainerfwd> incluir por ejemplo.