2015-10-29 13 views
5

Sto provando a costruire un oggetto in una mappa che contiene un atomico, quindi non può essere né copiato né spostato AFAICT.Costruisci un oggetto non modificabile in una mappa

La mia lettura di C++ reference è che la mappa emplace dovrebbe essere in grado di farlo. Ma il seguente codice non viene compilato a causa di costruttori eliminati o inesistenti. Utilizzare make_pair non aiuta.

#include <atomic> 
#include <unordered_map> 

class Z { 
    std::atomic<int> i; 
}; 

std::unordered_map<int, Z> map; 

void test(void) { 
    map.emplace(0, Z()); // error 
    map[0] = Z(); // error 
} 

È possibile, e in caso contrario, perché no?

EDIT: compilatore gcc 4.8.1 è, in Linux

+1

Che compilatore si usa? – Drop

+2

'emplace' prende gli argomenti del costruttore, ma stai passando un oggetto temporaneo. –

+0

@NeilKirk Quindi in quale altro modo si potrebbe invocare il costruttore no-arg? –

risposta

13

map.emplace(std::piecewise_construct, std::make_tuple(0), std::make_tuple()) costruirà uno zero-argomento Z a posizione 0.

map[0] lo farà anche se non è già lì.

emplace accetta gli argomenti per creare un std::pair<const K, V>. std::pair ha un costruttore con tag std::piecewise_construct_t che accetta due tuple, il primo è utilizzato per costruire il primo argomento, il secondo per costruire il secondo argomento.

così std::pair<const int, Z> test(std::piecewise_construct, std::make_tuple(0), std::make_tuple()) costruisce gli elementi test sul posto, il const int è costruito con (0). Il Z è costruito con ().

map.emplace in avanti è argomenti per il costruttore std::pair.

2

La soluzione più semplice è utilizzare operator[] per costruire il valore all'interno della mappa. Quindi puoi assegnare un valore (o operare su di esso secondo necessità).

-1

può essere la seguente soluzione sarà migliore, dal momento che non è copiabile atomica:

class Z { 
    std::atomic<int> i; 
}; 

std::unordered_map<int, std::shared_ptr<Z>> map; 

void test(void) { 
    map.emplace(0, std::make_shared<Z>()); // OK 
} 
+0

L'overhead di 'shared_ptr' non è banale. –

Problemi correlati