3

J'ai un problème avec l'utilisation de la liste d'adjacence de la bibliothèque graphique Boost. Il semble être un problème de dépendance circulaire: J'ai un typedef T d'un modèle qui utilise une certaine classe A. De plus, A stocke un pointeur sur un objet de type T. Maintenant, le compilateur me dit que T ne nomme pas un type.Comment résoudre Boost :: BGL modèle <-> classe dépendance circulaire?

Voici excerptions de mes fichiers plus concrets:

//graphdefinitions.hpp 
#include "lane.hpp" 
#include "tie.hpp" 

typedef boost::adjacency_list<boost::listS, boost::listS, 
           boost::directedS, Tie, Lane> Map; 
typedef boost::graph_traits<Map>::edge_descriptor edge_descriptor; 

//lane.hpp 
#include "graphdefinitions.hpp" 
class Lane { 
    ... 
    edge_descriptor *left, *right; 
}; 

//tie.hpp 
//no important includes here 
class Tie { 
    ... 
}; 

Comment puis-je résoudre ce problème d'ordre inclusion dépendance /?

UN AUTRE ÉDITION: J'ai juste eu l'idée que le type d'un edge_descriptor pourrait être un primitif comme int. Cela aurait résolu le problème car j'aurais pu remplacer les descripteurs edge_descriptors de Lane par des variables int, ce qui aurait pu supprimer l'inclusion de graphdefinitions.hpp dans tie.hpp. Malheureusement, mon idée était cra * et je dois trouver une autre solution. Les types Edge_descriptor semblent être là pour une raison ...

Répondre

0

Vous avez des en-têtes inclus circulairement. Lane comprend des définitions de graphes, qui comprennent une voie, qui comprend des définitions de graphes, etc. Ceci est la cause de votre problème. Edit: J'ai réalisé que cela était déjà mentionné dans l'OP. La solution à ce problème est PIMPL. Edit: Ce que je voudrais faire est de mettre le typedef dans la classe Lane. Cela devrait résoudre le problème de la manière la plus nette.

+0

Exactement! Mais la question est: Qu'est-ce qu'une alternative (de travail!) À cette approche? J'ai aussi déjà essayé de transférer simplement Tie et Lane à l'intérieur de graphdefinitions.hpp qui n'était pas non plus accepté par le compilateur. – Bastian

+0

@Bastian: Utilisez PIMPL pour implémenter Lane. – Puppy

+0

@DeadMG: S'il vous plaît jeter un oeil à mon dernier message. – Bastian

0

Je ne pense vraiment pas que vous ayez besoin de quelque chose de spécial à propos de ce code. Vous devez vous assurer que les définitions des types utilisés dans le graphique sont déclarées (non seulement déclarées à l'avance).

+0

Donc, ce que vous suggérez est que je devrais inclure les fichiers d'en-tête des types qui sont utilisés?Si je le fais, le compilateur commence à se plaindre de la carte: "n'a pas été déclaré" dans tous les fichiers qui utilisent Map. – Bastian

+0

La commande de ces types de dépendances de type est parfois difficile. Vous devriez indiquer quels types sont définis dans quels fichiers d'en-tête, et comment sont-ils inclus pour obtenir une meilleure réponse. –

+0

Ok, c'est fait :-). La structure est assez simple ce qui n'aide pas un peu ... – Bastian

0

@DeadMG: J'ai utilisé une approche de type PIMPL maintenant et je pense que cela a résolu mon problème.

Alors qu'est-ce que j'ai fait? J'ai changé Lane classe de regarder cette façon:

//lane.hpp 
#include "graphdefinitions.hpp" 

class LaneSide; 
class Lane { 
public: 
    const LaneSide getLeft() const; 
    const LaneSide getRight() const; 
    ... 
private: 
    LaneSide *left; 
    LaneSide *right; 
    ... 
}; 

Et la Laneside classe qui est pratiquement juste un indirection et détient le type de valeur que je ne pouvais pas en avant de déclarer à l'intérieur de lane.hpp, regarde cette chemin:

//laneside.hpp 
class LaneSide 
{ 
    edge_descriptor* edge; 
}; 

Cela semble tromper le compilateur comme je l'ai voulu. Alors merci pour l'indice DeadMG. Ce que je me demandais: Est-il également possible de stocker un objet LaneSide à l'intérieur de la classe Lane non pas comme un pointeur mais plutôt comme un objet réel? J'ai essayé cela en premier mais le compilateur s'est plaint de la construction. Et je me demande aussi s'il existe un moyen d'éviter la consommation de mémoire supplémentaire. Lorsque mon graphique devient assez grand, cela pourrait éventuellement devenir pertinent.

7

Il existe une classe de traits non bien documentée dans BGL qui donne les types de vertex et de descripteur de bord pour un graphique adjacency_list sans avoir besoin de connaître les types de propriété. Il est conçu pour exactement le cas d'utilisation que vous avez. Regardez dans la section "Types associés" de http://www.boost.org/doc/libs/1_45_0/libs/graph/doc/adjacency_list.html et notez qu'il existe deux définitions pour vertex_descriptor et edge_descriptor; vous pouvez utiliser les versions provenant de adjacency_list_traits dans les définitions de vos ensembles de propriétés sans provoquer de définition circulaire.

Questions connexes