2016-05-05 16 views
8

Czy punkt, w którym std::map::emplace tworzy obiekt (np. Wywołanie konstruktora) określony jakoś w standardzie? Jeśli tak, czy zdarza się przed istnienie takiego klucza jest sprawdzane lub po?W którym punkcie map :: emplace utworzymy obiekt?

Jest wiele spraw w przypadkach, jak następuje:

struct X {}; 
std::map<int, std::unique_ptr<X> > map; 

void f(int x) { 
    map.emplace(x, new X); 
} 

Jeśli obiekt jest tworzony po pierwsze, wszystko jest cool (unique_ptr jest zbudowany i posiada zasób), ale jeśli to jest skonstruowany po sprawdzeniu, nie to przeciek pamięci w przypadku duplikatu klucza.

Wszystko udało mi się znaleźć w normie jest

wstawia obiekt VALUE_TYPE t zbudowane z std::forward<Args>(args)... tylko wtedy, gdy istnieje żaden element w kontenerze z kluczem odpowiednikiem klawisza t.

która nie odnosi się do pytania, które mam.

+8

Mimo to używanie 'nowej T' na liście argumentów jest złe, więc" prawdziwą "odpowiedzią jest" Nie rób tego ". Użyj 'make_unique ()' i teraz nigdy nie wycieka. – GManNickG

+1

W razie wypadku wystąpi wyciek, jeśli alokacja nie powiedzie się. –

+1

Zazwyczaj nie umieszcza się inteligentnych wskaźników, ponieważ ich kopiowanie/przenoszenie jest szybkie i bezpieczne. Twoje pytanie miałoby więcej sensu, gdyby było 'map ' – Fozi

Odpowiedz

12

To jest w rzeczywistości niedookreślone, częściowo dlatego, że C++ 17 dodał try_emplace, aby ustalić semantykę. N3873, wczesna wersja propozycji try_emplace, ma dobrą dyskusję na temat istniejącego brzmienia.

W ogólnym przypadku musi to być "przed", ponieważ "po" jest niemożliwe do nałożenia, a standard byłby wadliwy, gdyby nałożył taki wymóg. Rozważ emplace(piecewise_construct, forward_as_tuple(foo, bar), forward_as_tuple(meow, purr)). Ponieważ klucz i wartość nie muszą być ruchome, musisz najpierw zbudować obiekt i sprawdzić drugie istnienie klucza, ponieważ nie można sprawdzić istnienia klucza bez klucza.

Nie można jednak wykluczyć, że wdrożenie może wymagać specjalnego przypadku: emplace(key_type, something); Zazwyczaj jest to Dobra rzecz, aby uniknąć płacenia za wymagany przydział + budowanie + zniszczenie + dealokacja, gdy klucz istnieje.

+0

Kompletny i bardzo edukacyjny, jak zawsze. – SergeyA

Powiązane problemy