Voglio collocare un oggetto in un std::map
il cui costruttore non accetta alcun argomento. Tuttavia, std::map::emplace
sembra richiedere almeno un argomento aggiuntivo oltre alla chiave. Quindi, come posso inoltrare zero argomenti al costruttore?Come collocare un oggetto con un costruttore senza argomenti in std :: map?
risposta
Il tipo di elemento di std::map<K, V>
è in realtà std::pair<K, V>
, in modo che quando si sta emplacing in una mappa, gli argomenti sarà trasmesso al costruttore di std::pair
. Ecco perché non puoi passare solo la chiave: std::pair<K, V>
non può essere costruita da un singolo argomento (a meno che non sia un'altra coppia dello stesso tipo). Puoi passare zero argomenti, ma la chiave sarà inizializzata dal valore, che è probabilmente non è quello che vuoi.
Nella maggior parte dei casi, i valori in movimento sarà a buon mercato (e le chiavi sarà piccola e copiabile) e si dovrebbe davvero solo fare qualcosa di simile:
M.emplace(k, V{});
dove V
è il tipo mappato. Sarà inizializzato a valore e spostato nel contenitore. (La mossa potrebbe anche essere eli- minata, non ne sono sicuro)
Se non è possibile spostarsi e si ha veramente bisogno che lo V
sia costruito sul posto, è necessario utilizzare il costruttore di costruzione a tratti ...
M.emplace(std::piecewise_construct, std::make_tuple(k), std::make_tuple());
Questo provoca std::pair
per costruire il primo elemento utilizzando k
e il secondo elemento con zero argomenti (valore di inizializzazione).
È possibile creare in modo esplicito un pair
e passarlo a map::emplace
oppure utilizzare lo piecewise construction constructor di std::pair
.
struct foo {};
std::map<int, foo> m;
m.emplace(std::pair<int, foo>(1, {}));
m.emplace(std::piecewise_construct,
std::forward_as_tuple(2),
std::forward_as_tuple());
Ho avuto lo stesso problema quando ho dovuto creare un std::map
di oggetti std::mutex
. Il problema è che std::mutex
non è né copiabile né mobile, quindi ho dovuto costruirlo "sul posto".
La risposta accettata non funziona per questo caso (M.emplace(k, V{});
ha bisogno che V sia mobile). E non volevo usare l'opzione std::piecewise_construct
complicata e meno leggibile (vedi sopra in altre risposte).
La mia soluzione è molto più semplice: basta usare il operator[]
- creerà il valore utilizzando il suo costruttore predefinito e restituirà un riferimento ad esso. Oppure troverà e restituirà un riferimento all'elemento già esistente senza crearne uno nuovo.
std::map<std::string, std::mutex> map;
std::mutex& GetMutexForFile(const std::string& filename)
{
return map[filename]; // constructs it inside the map if doesn't exist
}
- 1. È sicuro ottenere un oggetto in std :: map per riferimento?
- 2. Come restituire un oggetto senza costruttore di copia
- 3. Una classe può avere un costruttore con modello senza argomenti?
- 4. std :: map emplace senza valore di copia
- 5. Come implementare un allocatore personalizzato da utilizzare con std :: map?
- 6. Come istanziare un oggetto con un costruttore privato in C#?
- 7. Come utilizzare std :: enable_if per selezionare condizionatamente un costruttore variadic?
- 8. Un costruttore è sempre un oggetto funzione?
- 9. elementi Inserire le std :: map senza copiare in più
- 10. std :: map con std :: chiave weak_ptr
- 11. In C++, è un costruttore con solo argomenti predefiniti un costruttore predefinito?
- 12. utilizzando BOOST_FOREACH con std :: map
- 13. Passare argomenti a un costruttore statico in Java?
- 14. Passando tutti gli argomenti a un costruttore
- 15. Utilizzo di std :: map <K,V> dove V non ha un costruttore predefinito utilizzabile
- 16. Come aggiungere una chiave valida senza specificare un valore in una std :: map?
- 17. Mock un oggetto con un costruttore - Rhino Mocks
- 18. Come std :: find utilizzando un oggetto Confronta?
- 19. Usa std :: reference_wrapper in std :: map
- 20. Argomenti costruttore costruttore ES6
- 21. Devo std: spostare un shared_ptr in un costruttore di move?
- 22. Perché non dovrei istanziare un oggetto stringa con un costruttore?
- 23. Come passare argomenti a un costruttore non predefinito?
- 24. Utilizzo di std :: reference_wrapper come chiave in una std :: map
- 25. Come convertire std :: array in un punto?
- 26. std :: map thread-safety
- 27. Chiama un costruttore da argomenti variabili con PHP
- 28. Come passare std :: map come parametro costruttore di default in C++ funzione della classe
- 29. Doxygen riconosce std :: shared_ptr o std :: map
- 30. Mappatura std :: map a Python
Perché non 'forward_as_tuple' invece di' make_tuple'? – Yakk
@Yakk Bene, in questo caso, per risparmiare un po 'di digitazione. Ovviamente ci sono casi in cui è necessario 'forward_as_tuple'. – Brian
Si noti che un semplice 'M [k];' avrà lo stesso effetto di quel malarkey 'piece_construct'. –