Qual è la differenza tra unordered_map :: emplace e unordered_map :: insert in C++?Qual è la differenza tra unordered_map :: emplace e unordered_map :: insert in C++?
risposta
unordered_map::insert
copia o sposta una coppia chiave-valore nel contenitore. It is overloaded to accept reference-to-const or an rvalue reference:
std::pair<iterator,bool> insert(const std::pair<const Key, T>& value);
template<class P>
std::pair<iterator,bool> insert(P&& value);
unordered_map::emplace
consente di evitare copie non necessarie o si muove costruendo l'elemento al suo posto. Si utilizza l'inoltro perfetto e un modello variadic a forward arguments to the constructor of the key-value pair:
template<class... Args>
std::pair<iterator,bool> emplace(Args&&... args);
Ma c'è una grande quantità di sovrapposizione tra le due funzioni. emplace
può essere utilizzato per inoltrare al costruttore copia/sposta della coppia chiave-valore che consente di utilizzarlo nello stesso modo di insert
. Ciò significa che l'uso di emplace
non garantisce l'assenza di copie o spostamenti. Anche la versione di insert
che accetta un riferimento di rvalue è in realtà un modello e accetta qualsiasi tipo P
in modo tale che la coppia chiave-valore sia costruibile da P
.
In linea di principio, funzioni emplacement dovrebbe essere a volte più efficiente delle loro controparti di inserimento, e non devono mai essere inferiore efficiente.
(Edit: Howard Hinnant corse some experiments che ha mostrato a volte insert
è più veloce di emplace
)
Se sicuramente non desidera copiare/spostare nel contenitore potrebbe essere saggio usare insert
perché sei più probabilità di ottenere un errore di compilazione se si passano argomenti non corretti. Devi essere più attento a passare gli argomenti corretti alle funzioni di posizionamento.
La maggior parte delle implementazioni di unordered_map::emplace
causerà l'allocazione dinamica della memoria per la nuova coppia anche se la mappa contiene già un elemento con quella chiave e lo emplace
non riuscirà. Ciò significa che se c'è una buona probabilità che un emplace
fallisca, potresti ottenere prestazioni migliori usando insert per evitare allocazioni di memoria dinamica non necessarie.
piccolo esempio:
#include <unordered_map>
#include <iostream>
int main() {
auto employee1 = std::pair<int, std::string>{1, "John Smith"};
auto employees = std::unordered_map<int, std::string>{};
employees.insert(employee1); // copy insertion
employees.insert(std::make_pair(2, "Mary Jones")); // move insertion
employees.emplace(3, "James Brown"); // construct in-place
for (const auto& employee : employees)
std::cout << employee.first << ": " << employee.second << "\n";
}
Edit2: Su richiesta. È anche possibile utilizzare unordered_map::emplace
con una chiave o un valore che richiede più di un parametro del costruttore. Usando lo std::pair
piecewise constructor puoi comunque evitare copie o spostamenti non necessari.
#include <unordered_map>
#include <iostream>
struct Employee {
std::string firstname;
std::string lastname;
Employee(const std::string& firstname, const std::string& lastname)
: firstname(firstname), lastname(lastname){}
};
int main() {
auto employees = std::unordered_map<int, Employee>{};
auto employee1 = std::pair<int, Employee>{1, Employee{"John", "Smith"}};
employees.insert(employee1); // copy insertion
employees.insert(std::make_pair(2, Employee{"Mary", "Jones"})); // move insertion
employees.emplace(3, Employee("Sam", "Thomas")); // emplace with pre-constructed Employee
employees.emplace(std::piecewise_construct,
std::forward_as_tuple(4),
std::forward_as_tuple("James", "Brown")); // construct in-place
}
* "Le funzioni di posizionamento sono spesso più efficienti delle controparti di inserimento e non sono mai meno efficienti." * Howard Hinnant ha misurato qualcosa di diverso: http://htmlpreview.github.io/?https://github.com/HowardHinnant /papers/blob/master/insert_vs_emplace.html Vedi anche: https://groups.google.com/a/isocpp.org/forum/?fromgroups#!searchin/std-discussion/emplace/std-discussion/YQ4BGAvxIhw/jTfn1RIm9IkJ – dyp
@dyp vedere anche non funziona per me su mobile firefox – Yakk
@Yakk Ah, mi dispiace. Spero che funzioni: https://groups.google.com/a/isocpp.org/d/topic/std-discussion/YQ4BGAvxIhw/discussion 'emplace' per i contenitori associativi in genere crea l'elemento (non solo la chiave) dagli argomenti anche se non è inserito. Quindi se hai già un elemento (fuori dal contenitore associativo) e vuoi copiarlo, 'inserire' potrebbe essere più efficiente. – dyp
- 1. La differenza tra python dict e tr1 :: unordered_map in C++
- 2. Come scegliere tra la mappa e unordered_map?
- 3. è insert() necessario in una mappa o unordered_map?
- 4. forma più semplice di std :: unordered_map :: insert?
- 5. C++ - complessità unordered_map
- 6. C++ std :: complessità unordered_map
- 7. Scelta tra std :: map e std :: unordered_map
- 8. Come std :: unordered_map è implementato
- 9. iteratori bidirezionali in unordered_map?
- 10. C++ std :: vector emplace vs insert
- 11. Qual è l'interfaccia per l'uso dei bucket in std :: unordered_map?
- 12. C++ push_back vs Insert vs emplace
- 13. Perché unordered_map "trova + inserisci" più velocemente di "insert + check for success"?
- 14. std :: unordered_map vettore pedice nell'intervallo
- 15. Qual è la funzione di hash predefinita utilizzata in C++ std :: unordered_map?
- 16. C++ Come inserire la matrice in unordered_map come chiave?
- 17. Come usare unordered_map in Android?
- 18. Quando si usa std :: unordered_map :: emplace_hint?
- 19. lettura da unordered_map const
- 20. C++ unordered_map compilazione problema con g ++
- 21. Perché C++ 11/Boost `unordered_map` non rihash durante la cancellazione?
- 22. Qual è la differenza tra C# e visual C#?
- 23. Qual è la differenza tra C++ gestito e C#?
- 24. Differenza tra UPDATE e INSERT in Cassandra?
- 25. Qual è la differenza tra strtok_r e strtok_s in C?
- 26. Qual è la differenza tra popen() e system() in C
- 27. Qual è la differenza tra CLR e DLR in C#?
- 28. Qual è la differenza tra Delegate e Azione in C#
- 29. Qual è la differenza tra memset e memcpy in C
- 30. Qual è la differenza tra oggetti e classi in C#?
Tratto da un [riferimento] (http://en.cppreference.com/w/cpp/container/unordered_map/emplace): * uso attento della colloco permette al nuovo elemento da costruire evitando inutili copia o spostare le operazioni. Il costruttore del nuovo elemento (cioè 'std :: pair') viene chiamato con esattamente gli stessi argomenti forniti per emplace, inoltrato tramite 'std :: forward (args) ...'. * –
chris
emplace crea un nuovo oggetto mentre insert prende un oggetto esistente.I parametri sono diversi poiché emplace accetta gli argomenti del costruttore. Se non si dispone di un'istanza già esistente da inserire, utilizzare emplace. –