2017-10-16 1 views
4

Quelqu'un a suggéré here en utilisant des tuples au lieu de toutes les structures publiques. Et je l'ai trouvé utile. Mais mon problème est maintenant avec la section suivante:Dépendance circulaire dans les arguments de modèle

using Edge = std::tuple<Node_wp,//From Node 
         Node_wp>;//To Node 
using Edge_wp = std::weak_ptr<Edge>; 

using Node = std::tuple<std::vector<Edge_wp>,//Incoming Edges 
         std::vector<Edge_wp>>;//Outgoing Edges 
using Node_wp = std::weak_ptr<Node>; 

Comment puis-je surmonter cette dépendance circulaire dans les paramètres de modèle. La déclaration en avant (avec la connaissance en ma possession) ne fonctionnera pas puisque le type Bord ne peut pas être formé sans connaître le type nœud et vice versa.

Évidemment, je peux faire l'un d'entre eux struct et être fait avec. Mais il sera moche de briser la symétrie dans l'accès.

+2

na pas lu la réponse liée, mais je suis en désaccord avec la prémisse, juste préférer struct sur tuples. Si votre edge connecte 'Node_wp's alors pourquoi ne pas le déclarer comme tel? De plus, 'from_node' et' to_node' seraient de bien meilleurs noms que 'first' et' second'. – user463035818

+0

@ tobi303 Ils suggèrent d'utiliser 'enum' pour plus de lisibilité. Mais la vraie capture ici n'est pas l'implémentation des fonctions membres (tri, égalité, sérialisation, etc.) qui font déjà partie de 'tuple' (ou bibliothèques supportant tuple). – ifyalciner

Répondre

5

Vous pouvez utiliser struct et l'héritage public pour résoudre votre problème de dépendance circulaire. Node deviendra une enveloppe struct autour d'un std::tuple:

#include <memory> 
#include <tuple> 
#include <vector> 

struct Node; 
using Node_wp = std::weak_ptr<Node>; 

using Edge = std::tuple<Node_wp, // From Node 
         Node_wp>; // To Node 
using Edge_wp = std::weak_ptr<Edge>; 

struct Node : std::tuple<std::vector<Edge_wp>, // Incoming Edges 
         std::vector<Edge_wp>> // Outgoing Edges 
{ 
    using std::tuple<std::vector<Edge_wp>, std::vector<Edge_wp>>::tuple; 
}; 
+0

C'est parfait. Je vous remercie. – ifyalciner

+0

@ifyalciner Pourquoi cette réponse a-t-elle été acceptée? C'est en fait la même chose que la solution initialement proposée: "Je peux évidemment en structurer un". – VTT

+1

@VTT ce que je voulais dire utilisait struct comme lui-même (je ne pouvais pas penser à utiliser l'héritage pour casser le cercle). Maintenant struct wrapper est juste une couverture superficielle sur tuple. Et je peux l'utiliser comme tuple. Mais si vous avez d'autres suggestions au lieu de l'héritage, je voudrais entendre aussi. – ifyalciner