Question

J'aimerais avoir deux structures qui pointent l'une vers l'autre.Plus précisément, j'aimerais avoir ce qui suit :

template<typename Key, typename Value> 
class MyStructure {
public:
  typedef map<Key, list<pair<Value, typename ListType::iterator>>> MapType;
  typedef list<typename MapType::element_type::iterator> ListType;
private:
  MapType map_;
  ListType list_;
}

Évidemment, cela ne fonctionnera pas puisque ListType n’est pas déclaré précédemment en tant que type.Comment pourrais-je faire ça ?Comme vous pouvez le voir, j'utilise les types d'itérateur comme pointeurs vers les éléments de ces deux structures.

Je pensais utiliser le modèle de modèle curieusement récurrent, mais je ne parvenais à rien avec cela.Quelqu'un sur ##c++ a également suggéré d'utiliser des alias de modèles, mais cela a également échoué (du moins, je ne sais pas comment utiliser cette idée).

Est-ce que je fais quelque chose de mal, conceptuellement ?Ou peut-être « pas conforme aux concepts C++ » ?Je pourrais certainement le faire avec des void*s, mais j'essaie de faire les choses de la bonne façon :)

Merci!

Était-ce utile?

La solution

Même si je soupçonnais qu'il pourrait s'agir d'un doublon (et c'est le cas à bien des égards), "Salut et salut.- Alf" a raison de souligner que la question en double potentielle concernait spécifiquement l'utilisation de typedef pour ce genre de chose.

Cependant, dans la présente question, le PO aimerait savoir comment aborder de manière générale l'inclusion mutuelle dans le scénario décrit dans la question.

Voici une suggestion :

#include <list>
#include <map>

template <typename Key, typename Value>
class MyElement;

template <typename Key, typename Value>
class MyStructure
{
public:
  typedef std::map<Key,MyElement<Key,Value> > MapType;
  typedef std::list<MyElement<Key,Value> >    ListType;
};

template <typename Key, typename Value>
class MyElement {
public:
  typename MyStructure<Key,Value>::MapType::iterator  map_iterator;
  typename MyStructure<Key,Value>::ListType::iterator list_iterator;
};

Comme vous pouvez le voir, j'ai introduit un nouveau type de données MyElement, qui contient l'itérateur de liste ainsi que l'itérateur de carte.Parce qu'il s'agit d'une classe plutôt que d'un typedef, elle peut être déclarée en avant.

Autres conseils

Ce n’est malheureusement pas possible, tel que vous l’exprimez.

Par contre, il me semble que (compte tenu de vos exigences) vous pourriez inverser le stockage.

Et si vous utilisiez un list de la Values, et ensuite la carte a-t-elle pointé vers cette liste ?

Cela briserait la dépendance cyclique.

typedef std::list< std::pair<Key, Value> > ListType;
typedef std::multiset<typename ListType::iterator, CmpFirst> MapType;

(Je ne sais pas si j'ai vraiment compris ce que vous essayiez de réaliser...)

Une autre solution que vous devriez probablement envisager est de voir si vous pouvez exprimer cela en termes de Boost.MultiIndex.Lorsque plusieurs itérations/modèles de recherche sont nécessaires, Boost.MultiIndex est souvent une meilleure alternative qu'une solution artisanale, car il entrelace les index dans les valeurs afin de minimiser le stockage.De plus, la cohérence (c'est-à-dire que tous les index font référence au même ensemble d'éléments) est une évidence.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top