std::map
sposta valori già inseriti quando si inseriscono nuovi dati?std :: mappa e comportamento dei dati già inseriti
risposta
La mappa viene implementata come un albero e quando si inserisce un nuovo elemento, potrebbe essere necessario riequilibrare l'albero.
Questo valore non annulla qualsiasi iteratore o riferimento a elementi nell'albero. Questo bilanciamento viene effettuato tramite la manipolazione di puntatori, quindi non hai nulla di cui preoccuparti; i nodi stessi rimangono fermi.
Il bilanciamento comporta la modifica della struttura dell'albero dicendo ai nodi quali sono i loro figli, genitori e fratelli tramite i puntatori di riassegnazione, ma questo è un dettaglio di implementazione. Logicamente non è cambiato nulla.
Lo standard non richiede specifiche implementazioni del STL, solo il comportamento e le caratteristiche di runtime. Detto questo, una skip list o un albero è un'implementazione molto probabile di std :: map, quindi i collegamenti verranno aggiornati e l'ordine relativo cambierà, ma i dati reali non verranno spostati.
consideri un nodo tipico in lista doppiamente collegata:
template <class T>
struct Node
{
Node* mPrevious;
Node* mNext;
T mValue;
};
Quando si inserisce un nuovo nodo tra due esistenti, tutto ciò che dovete fare è un po 'ricablaggio.
void insert(Node* target, Node* newNode)
{
target->mPrevious->mNext = newNode;
target->mPrevious = newNode;
newNode->mPrevious = target->mPrevious;
newNode->mNext = target;
}
Il comportamento è simile con un std::map
(o std::set
, std::multimap
o std::multiset
poiché sono tutti implementati utilizzando la stessa struttura di base in generale).
Significa che qualsiasi iteratore che punta a un elemento esistente rimane anch'esso valido. Insisto sull'elemento esistente bit. L'iteratore restituito da end
deve essere ricalcolato dopo l'inserimento o la rimozione ed è preferibile non essere memorizzato nella cache.
Lo standard C++ non determina l'implementazione di std::map
solo il suo comportamento e l'efficienza. Le implementazioni sono autorizzate a spostare oggetti in giro; tuttavia, questo potrebbe essere inefficiente.
La maggior parte dei container std::map
viene implementata utilizzando una struttura dati ad albero con collegamenti. Quando si inseriscono o riordinano gli elementi, i collegamenti vengono modificati, ma i dati non vengono spostati. Lo spostamento di elementi rallenterebbe il tempo di esecuzione di std::map
.
- 1. std :: movimento e mappa assegnazione
- 2. std :: vector e std :: comportamento min
- 3. std :: mappa dei puntatori funzione membro?
- 4. std :: funzione e il comportamento
- 5. std :: cambio di mappa key_comp dopo l'inizializzazione
- 6. std :: map operator [] - comportamento non definito?
- 7. std :: string s() comportamento strano
- 8. strano comportamento di std :: is_nothrow_destructible
- 9. Errore mappa STL: nessun modello denominato 'mappa' nello spazio dei nomi 'std'; intendevi "max"?
- 10. std C++ elemento contenitore distruzione e comportamento inserimento
- 11. Ordinamento di std :: mappa per valore prima dell'output e destroy
- 12. std :: map ordina per dati?
- 13. Comportamento strano dei distruttori C++
- 14. il comportamento di std :: async con std :: launch :: politica async
- 15. Comportamento di GCC con std :: async (std :: launch :: async) rispetto al comportamento di Clang
- 16. Osservazione del comportamento strano con 'auto' e std :: minmax
- 17. E & vec [0] comportamento definito per un vd std :: vector?
- 18. Dati non inseriti nel database Sqlite in Android
- 19. MongoDb Streaming dei dati inseriti in tempo reale (o quasi in tempo reale)
- 20. Comportamento dei trasduttori Clojure
- 21. Come ottenere le identità dei record di dati inseriti utilizzando la copia bulk SQL
- 22. Boost.Bind per accedere std :: elementi della mappa in std :: for_each
- 23. std :: mappa per piccole raccolte sparse
- 24. Struttura dati di mantenimento dei ranghi diversa da std :: vector?
- 25. C++ Comportamento errato dell'inizializzazione std :: string
- 26. strano comportamento di std :: string con unicode
- 27. mappa vs lista; perché un comportamento diverso?
- 28. std :: lock_guard che causa un comportamento indefinito
- 29. Differenza tra std :: set e std :: priority_queue
- 30. mappa dei vettori in STL?
Mi chiedo, se 'it' è un iteratore di un elemento, quindi prima e dopo un inserimento' * it' si riferisce alla stessa voce di mappa ma è garantito che '& * it' rimane lo stesso? Nella maggior parte delle implementazioni mi aspetterei che questo sia vero, ma sarebbe possibile implementare un iteratore con sufficiente proxy che gli elementi potrebbero muoversi ma gli iteratori mantengono la coerenza. –
@Charles 23.1.2/8 afferma inoltre che nessun riferimento al contenitore viene invalidato. –
@Charles: bella domanda, non ci avevo mai pensato. Grazie a @Andreas per la risposta. – GManNickG