Se si utilizza C++ std :: map (e altri contenitori) con tipi di valore, si noterà che l'inserimento nella mappa chiama il distruttore per il tipo di elemento. Questo perché l'implementazione dell'operatore [] è richiesto dalle specifiche C++ per essere equivalente a questo:Perché C++ std :: map :: operator [] non usa inplace new?
(*((std::map<>::insert(std::make_pair(x, T()))).first)).second
Si chiama il costruttore di default del vostro tipo al fine di costruire quella coppia. Questo valore temporaneo viene quindi copiato nella mappa e quindi distrutto. La conferma di ciò può essere trovata in this stackoverflow post e here on codeguru.
Quello che trovo strano è che questo potrebbe essere implementato senza la necessità della variabile temporanea e comunque essere equivalente. C'è una funzionalità di C++ chiamata "inplace new". Std :: map e altri contenitori potrebbero allocare spazio vuoto per l'oggetto da vivere e quindi richiamare esplicitamente il costruttore predefinito dell'elemento nello spazio allocato.
La mia domanda: Perché nessuna delle implementazioni di std :: map che ho visto utilizzare inplace new per ottimizzare questa operazione? Mi sembra che migliorerebbe considerevolmente le prestazioni di questa operazione di basso livello. Ma molti occhi hanno studiato la base del codice STL, quindi immagino ci debba essere una ragione per cui viene fatto in questo modo.
Il test case è incluso nel post di stackoverflow collegato. Ecco di nuovo il collegamento: https://stackoverflow.com/questions/4017892/in-an-stl-map-of-structs-why-does-the-operator-cause-the-struct-dtor-to – srm
Mike Seymour: Quindi stai suggerendo che con il debugger disattivato, queste chiamate extra al distruttore sarebbero andate via? Sai che è vero? Anche se è vero, vuol dire che con il debugging, l'esecuzione è più difficile da eseguire il debug (non riesco a impostare un punto di interruzione nel mio debugger in cerca di problemi di ambito "reali"). È anche meno performante durante il debug, che è un problema minore, ma ancora reale. Entrambe queste ragioni mi sembrano motivi per utilizzare l'inplace new invece per una libreria di basso livello. – srm