Pourquoi le compilateur ne me laisse-t-il pas déclarer un typedef?
En supposant que c'est impossible, quelle est la meilleure pratique pour garder mon arbre d'inclusion petit?
c++
typedef
forward-declaration
user96825
la source
la source
typedef
nom d'un type de modèle multiniveau complexe utilisant une déclaration directe de cette façon est plutôt complexe et difficile. Sans oublier que cela pourrait nécessiter de plonger dans les détails d'implémentation cachés dans les arguments de modèle par défaut. Et la solution finale est un code long et illisible (en particulier lorsque les types proviennent de divers espaces de noms) très susceptible de changer de type d'origine.Pour ceux d'entre vous comme moi, qui cherchent à déclarer une structure de style C qui a été définie à l'aide de typedef, dans du code c ++, j'ai trouvé une solution qui va comme suit ...
la source
Pour "fwd declare a typedef", vous devez déclarer fwd une classe ou une structure, puis vous pouvez typedef déclaré le type. Plusieurs typedefs identiques sont acceptables par le compilateur.
forme longue:
forme courte:
la source
En C ++ (mais pas en C simple), il est parfaitement légal de taper un type deux fois, tant que les deux définitions sont complètement identiques:
la source
A
champs de cette manière carA
est vide par définition?Parce que pour déclarer un type, sa taille doit être connue. Vous pouvez transmettre déclarer un pointeur sur le type, ou typedef un pointeur sur le type.
Si vous le voulez vraiment, vous pouvez utiliser l'idiome pimpl pour réduire les inclusions. Mais si vous souhaitez utiliser un type plutôt qu'un pointeur, le compilateur doit connaître sa taille.
Edit: j_random_hacker ajoute une qualification importante à cette réponse, fondamentalement que la taille doit être connue pour utiliser le type, mais une déclaration directe peut être faite si nous avons seulement besoin de savoir que le type existe , afin de créer des pointeurs ou des références à la type. Étant donné que l'OP n'affichait pas de code, mais se plaignait qu'il ne se compilerait pas, j'ai supposé (probablement correctement) que l'OP essayait d' utiliser le type, pas seulement de s'y référer.
la source
L'utilisation de déclarations avancées au lieu d'un
#include
s complet n'est possible que lorsque vous n'avez pas l' intention d'utiliser le type lui-même (dans la portée de ce fichier) mais un pointeur ou une référence à celui-ci.Pour utiliser le type lui-même, le compilateur doit connaître sa taille - d'où sa déclaration complète doit être vu - d'où un plein
#include
est nécessaire.Cependant, la taille d'un pointeur ou d'une référence est connue du compilateur, quelle que soit la taille de la pointe, donc une déclaration directe est suffisante - elle déclare un nom d'identificateur de type.
Fait intéressant, lorsque vous utilisez un pointeur ou une référence à des types
class
oustruct
, le compilateur peut gérer les types incomplets, vous évitant ainsi de déclarer les types de pointe également:la source
J'ai eu le même problème, je ne voulais pas jouer avec plusieurs typedefs dans différents fichiers, donc je l'ai résolu avec l'héritage:
était:
fait:
A fonctionné comme un charme. Bien sûr, j'ai dû changer toutes les références de
simplement
la source
J'ai remplacé le
typedef
(using
pour être précis) par l'héritage et l'héritage du constructeur (?).Original
Remplacé
De cette façon, j'ai pu transmettre déclarer
CallStack
avec:la source
Comme l'a noté Bill Kotsias, la seule façon raisonnable de garder les détails typedef de votre point privé et de les déclarer en avant est avec héritage. Vous pouvez cependant le faire un peu mieux avec C ++ 11. Considère ceci:
la source
Comme @BillKotsias, j'ai utilisé l'héritage et cela a fonctionné pour moi.
J'ai changé ce gâchis (qui nécessitait tous les en-têtes boost dans ma déclaration * .h)
dans cette déclaration (* .h)
et l'implémentation (* .cpp) a été
la source