An welchem ​​Punkt erstellt map :: emplace ein Objekt?

8

Ist der Punkt, an dem std::map::emplace das Objekt (d. h. Aufruf des Konstruktors) irgendwie im Standard definiert? Wenn ja, passiert bevor das Vorhandensein eines solchen Schlüssels überprüft wird oder danach?

Es ist sehr wichtig in den folgenden Fällen:

%Vor%

Wenn das Objekt zuerst erstellt wird, ist alles cool (unique_ptr ist konstruiert und besitzt die Ressource), aber wenn es nach der Überprüfung erstellt wird, gibt es einen Speicherverlust im Falle eines doppelten Schlüssels.

Alles, was ich in Standard finden konnte, ist

  

Fügt ein value_type-Objekt ein, das mit konstruiert wurde    std::forward<Args>(args)... wenn und nur wenn es kein Element in der   Container mit Schlüssel entspricht dem Schlüssel von t.

was nicht die Frage angeht, die ich habe.

    
SergeyA 05.05.2016, 21:09
quelle

1 Antwort

12

Dies ist in der Tat unterspezifiziert, was teilweise darauf zurückzuführen ist, dass C ++ 17 hinzugefügt try_emplace , um die Semantik zu nageln. N3873 , eine frühe Version des Vorschlags try_emplace , hat eine gute Diskussion über den bestehenden Wortlaut.

Im allgemeinen Fall muss es "vorher" sein, da "nachher" nicht ausführbar ist, und der Standard wäre fehlerhaft, wenn er eine solche Anforderung auferlegt. Betrachte emplace(piecewise_construct, forward_as_tuple(foo, bar), forward_as_tuple(meow, purr)) . Da der Schlüssel und der Wert nicht beweglich sein müssen, müssen Sie das Objekt zuerst konstruieren und die Existenz des Schlüssels überprüfen, da Sie nicht ohne den Schlüssel nach dem Vorhandensein des Schlüssels suchen können.

Es ist jedoch nicht unvorstellbar, dass eine Implementierung den Sonderfall emplace(key_type, something) ; Es ist in der Regel eine gute Sache zu vermeiden, für die erforderliche Zuweisung zu zahlen + Konstruktion + Zerstörung + Freigabe, wenn der Schlüssel existiert.

    
T.C. 05.05.2016, 21:56
quelle

Tags und Links