Pregunta

Me gustaría tener dos estructuras que se apunten entre sí.Específicamente, me gustaría tener lo siguiente:

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_;
}

Obviamente esto no funcionará ya que ListType no está declarado previamente como tipo.¿Cómo podría hacer esto?Como puede ver, estoy usando los tipos de iterador como punteros a los elementos de estas dos estructuras.

Estaba pensando en usar el patrón de plantilla curiosamente recurrente, pero no pude llegar a ninguna parte con eso.Alguien en ##c++ también sugirió usar alias de plantilla, pero eso también falló (al menos, no sé cómo usar esta idea).

¿Estoy haciendo algo mal, conceptualmente?¿O quizás "no está en consonancia con los conceptos de C++"?Ciertamente podría hacer esto con void*s, pero estoy tratando de hacer las cosas de la manera correcta :)

¡Gracias!

¿Fue útil?

Solución

Aunque sospechaba que esto podría ser un duplicado (y en muchos sentidos lo es), "Saludos y saludos.- Alf" tiene razón al señalar que la posible pregunta duplicada se refería específicamente al uso de typedef para este tipo de cosas.

Sin embargo, en la presente pregunta, el OP quisiera saber cómo abordar en general la inclusión mutua en el escenario descrito en la pregunta.

Aquí hay una sugerencia:

#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;
};

Como puede ver, introduje un nuevo tipo de datos. MyElement, que contiene el iterador de la lista y el iterador del mapa.Debido a que es una clase en lugar de un typedef, se puede declarar hacia adelante.

Otros consejos

Lamentablemente esto no es posible, tal y como usted lo expresa.

Por otro lado me parece que (dados tus requerimientos) se podría revertir el almacenamiento.

¿Qué pasaría si usaras un list del Values, ¿Y luego el mapa apuntaba a esta lista?

Esto rompería la dependencia cíclica.

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

(Aunque no estoy seguro de haber entendido realmente lo que intentabas lograr...)

Otra solución que probablemente deberías considerar es ver si puedes expresar esto en términos de Impulso.MultiIndex.Cuando se necesitan varias iteraciones/patrones de búsqueda, Boost.MultiIndex suele ser una mejor alternativa que la solución hecha a mano, ya que intercala los índices dentro de los valores para minimizar el almacenamiento.Además, la coherencia (es decir, que todos los índices hagan referencia al mismo conjunto de elementos) es un hecho.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top