¿Por qué el compilador no me permite declarar un typedef?
Suponiendo que sea imposible, ¿cuál es la mejor práctica para mantener pequeño mi árbol de inclusión?
c++
typedef
forward-declaration
usuario96825
fuente
fuente
typedef
nombra un tipo de plantilla complejo de varios niveles que utiliza una declaración directa de esta manera, es bastante complejo y difícil. Sin mencionar que podría requerir sumergirse en detalles de implementación ocultos en los argumentos de plantilla predeterminados. Y la solución final es un código extenso e ilegible (especialmente cuando los tipos provienen de varios espacios de nombres) muy propensos a cambiar en el tipo original.Para aquellos de ustedes como yo, que buscan declarar hacia adelante una estructura de estilo C que se definió usando typedef, en algún código de C ++, he encontrado una solución que sigue de la siguiente manera ...
fuente
Para "fwd declarar un typedef" necesita fwd declarar una clase o una estructura y luego puede escribir typedef declarado tipo. Múltiples definiciones de tipo idénticas son aceptables por el compilador.
forma larga:
forma corta:
fuente
En C ++ (pero no en C simple), es perfectamente legal escribir un tipo dos veces, siempre y cuando ambas definiciones sean completamente idénticas:
fuente
A
campos de esta manera ya queA
está vacío por definición?Porque para declarar un tipo, su tamaño necesita ser conocido. Puede reenviar declarar un puntero al tipo, o typedef un puntero al tipo.
Si realmente quieres, puedes usar el modismo de pimpl para mantener bajas las inclusiones. Pero si desea utilizar un tipo, en lugar de un puntero, el compilador debe conocer su tamaño.
Editar: j_random_hacker agrega una calificación importante a esta respuesta, básicamente que se necesita saber el tamaño para usar el tipo, pero se puede hacer una declaración hacia adelante si solo necesitamos saber que el tipo existe , para crear punteros o referencias al tipo. Como el OP no mostró código, pero se quejó de que no se compilaría, supuse (probablemente correctamente) que el OP estaba tratando de usar el tipo, no solo referirme a él.
fuente
El uso de declaraciones adelantadas en lugar de un total de
#include
s es posible sólo cuando se está sin la intención de utilizar el tipo en sí (en el ámbito de este archivo), pero un puntero o referencia a ella.Para usar el tipo en sí, el compilador debe conocer su tamaño, por lo tanto, debe verse su declaración completa, por lo tanto,
#include
se necesita un completo .Sin embargo, el compilador conoce el tamaño de un puntero o referencia, independientemente del tamaño del puntero, por lo que una declaración directa es suficiente: declara un nombre de identificador de tipo.
Curiosamente, cuando se usa puntero o referencia a
class
ostruct
tipos, el compilador puede manejar tipos incompletos ahorrándole la necesidad de declarar también los tipos de puntas:fuente
Tuve el mismo problema, no quería meterme con múltiples typedefs en diferentes archivos, así que lo resolví con la herencia:
estaba:
hizo:
Trabajado como un encanto. Por supuesto, tuve que cambiar cualquier referencia de
simplemente
fuente
Reemplacé el
typedef
(using
para ser específico) con herencia y herencia de constructor (?).Original
Sustituido
De esta manera pude reenviar la declaración
CallStack
con:fuente
Como señaló Bill Kotsias, la única forma razonable de mantener privados los detalles de typedef de su punto, y declararlos de antemano es mediante herencia. Sin embargo, puedes hacerlo un poco mejor con C ++ 11. Considera esto:
fuente
Al igual que @BillKotsias, utilicé la herencia, y funcionó para mí.
Cambié este desastre (que requería todos los encabezados de impulso en mi declaración * .h)
en esta declaración (* .h)
y la implementación (* .cpp) fue
fuente