2014-07-19 12 views
5

Ho un std::map e uno std::list. Voglio che gli elementi nei contenitori abbiano il tipo di iteratore del contenitore opposto.Contenitore stl riferito a Typedef

Come posso digitarli?

Esempio:

typedef std::map<MyKeyClass, typename MyList::iterator> MyMap; 
//         ^MyList not defined. 
typedef std::list<typename MyMap::iterator> MyList; 

Naturalmente invertendo le due linee non funziona.

Ho anche provato

typedef std::map<MyKeyClass, 
        typename std::list<typename MyMap::iterator>::iterator> MyMap; 
typedef std::list<typename MyMap::iterator> MyList; 

, ma che non ha funzionato neanche.

UPDATE: Il motivo per cui ho bisogno di questo è di tenere traccia delle coppie chiave/valore per 2 aspetti degli ordini. Diciamo che ho un map<KEY,VALUE>. È ordinato per KEY e trovare un valore con una chiave è veloce. Ma voglio anche tenere traccia dei valori per il momento in cui viene aggiunto il valore. Voglio sapere quale valore è aggiunto di recente. Per fare questo uso lista. La ragione per cui ho bisogno di un iteratore per tornare all'elenco dalla mappa è cancellare un elemento nei contenitori. Quando cancello un elemento nella mappa con un tasto, devo anche cancellare un elemento nell'elenco. Ho anche bisogno del contrario (cancellando il valore meno recente). Ho scoperto che la mia idea di usare esplicitamente i puntatori (come nei commenti) non funziona perché ho bisogno effettivamente di un iteratore per cancellare un elemento nei contenitori.

UPDATE2: Lo chiedo perché mi sono sentito un po 'strano che non posso farlo. Uso spesso il contenitore STL come struttura dati di base (come fanno tutti). Ad esempio, std::map può essere utilizzato in alternativa all'implementazione di un albero binario con struct e puntatori espliciti. I contenitori STL sono ben progettati e non ho mai provato che non possa usare il container STL per esprimere alcune strutture che possono essere fatte da struct e pointer. Non possono garantire che il contenitore STL abbia la stessa proprietà di struct e la struttura del puntatore. Ma ancora, con una struttura così semplice, mi sentivo un po 'strano che non potessi esprimerlo con i contenitori STL.

+0

Questo è come 'struct X {Y y; }; struct Y {X x; }; ', non è vero? –

+0

Sì, ma in tal caso possiamo utilizzare la dichiarazione anticipata. Come posso farlo con il mio esempio? AGGIORNAMENTO: Spiacenti, non può essere eseguito dalla dichiarazione di inoltro perché non è un puntatore. Io uso l'iteratore come una sorta di puntatore qui. Quindi quello che voglio fare è qualcosa come la dichiarazione in avanti per l'iteratore ... Potrebbe non essere possibile pensare. –

+1

Non si ha alcun controllo sulla parte interna dei contenitori della libreria standard, quindi non si può affermare che "è come un puntatore". Lo standard dice che i tipi devono essere completi, punto. –

risposta

0

Quello che stai cercando di fare è impossibile perché crea una definizione ricorsiva senza fine.

considerare ciò che accade nella vostra prima typedef, il secondo esempio:

typedef std::map<MyKeyClass, 
    typename std::list<typename MyMap::iterator>::iterator> MyMap; 

Il MyMap interno sarebbe esteso, e si otterrebbe

typedef std::map<MyKeyClass, 
    typename std::list<typename std::map<MyKeyClass, 
     typename std::list<typename MyMap::iterator>::iterator>::iterator>::iterator> MyMap; 

E poi ci sarebbe stata un'altra MyMap lì espandere. Ora puoi vedere dove sta andando. Dovresti considerare cosa stai cercando di fare e vedere se non esiste un modo migliore per modellare la struttura dei dati.

0

L'unica ragione per cui mi chiedo perché è necessario questo tipo di ciclicità è perché la mappa memorizza i riferimenti agli elenchi e gli elenchi contengono riferimenti alla mappa. In altre parole, si desidera condividere i dati tra la mappa e gli elenchi. Utilizzare una mappa di std::shared_ptr s e un elenco di std::shared_ptr s, che consente di condividere facilmente gli elementi (quali sono i dati veri) tra le mappe e gli elenchi.

+0

Ho aggiornato la domanda. Sì, voglio condividere i dati tra la mappa e l'elenco. (Nel mio caso di domanda aggiornato VALUE è condiviso.). Ma mi chiedo ancora come posso cancellare un elemento nei contenitori, se necessario. –

1

Probabilmente stai cercando un contenitore multiindice, come quello trovato in boost. Ti permette di avere mappe/set ordinati e accessibili da più tipi di chiave.

Boost bimap è uno strumento simile, con solo due chiavi/indici, che consente essenzialmente di accedere a una mappa in base a chiave e valore.

+0

+1: Boost Multi-index e bimap forniscono anche supporto per "ordine cronologico" come indice (http://www.boost.org/doc/libs/1_55_0/libs/multi_index/doc/tutorial/, controlla l'esempio) –

0

Dopo tutto, ho scritto il codice qui sotto. È compilato da g ++.

struct ListEntry; 
typedef std::unordered_map<MyKeyClass, typename std::list<ListEntry>::iterator> KeyMap; 
struct ListEntry{ 
    typename KeyMap::iterator it;              
}; 
typedef std::list<ListEntry> MyList; 
Problemi correlati