Ich bin ein wenig von std::map::insert
‚s Semantik verwirrt. Ich meine, ich beschwere mich nicht - der Standard ist der Standard und die API ist so wie sie ist. Dennoch wirdRationale für die C++ - Standard-Map-Insert-Semantik?
die Einfügeoperation Prüfungen für jedes Element eingefügt ob ein weiteres Element bereits in dem Behälter mit dem gleichen Schlüssel Wert vorhanden ist, wenn dem so ist, wird das Element nicht eingesetzt und dessen zugeordneter Wert ist nicht in irgendeiner Weise verändert.
Und - nur in seinem Single-Argumente Version pair<iterator,bool> insert (const value_type& x);
wird es Ihnen auch sagen, wenn es auch den (neuen, möglicherweise unterschiedlichen) Wert auf die Taste (n) eingefügt. Soweit ich verstehe, werden die Iterator Versionen leise Einfügungen ignorieren, wenn der Schlüssel bereits vorhanden ist.
Für mich ist dies einfach Zähler intuitiv, Ich hätte erwartet, dass der Wert Teil überschrieben werden und der alte Wert Teil auf Einfügen verworfen werden. Offensichtlich ist die Designer des STL dachten anders - jemand kennt die (historische) Begründung oder eine gründliche Erklärung dafür geben, wie die bestehende Semantik (mehr) sinnvoll?
Am Beispiel:
Es gibt ein paar grundlegenden Möglichkeiten, Insert in einem einzigen Schlüsselkarte wie std::map
zu implementieren:
- einfügen, ersetzen, wenn bereits
- Einsatz vorhanden ist, ignorieren, wenn bereits vorhanden ist (dies ist das Verhalten von std :: map)
- Einsatz, Fehler melden, wenn bereits UB vorhanden
- Einsatz, wenn bereits vorhanden
ich jetzt versuchen, zu verstehen, warum insert_or_ignore
mehr Sinn als insert_or_replace
(oder insert_or_error
) macht!
Ich schaute in meine Kopie von TC++PL (leider nur ich die deutsche Ausgabe haben), und interessanterweise Stroustrup schreibt in Kapitel 17.4.1.7 (Listenoperationen für Karte): (sorry Rohübersetzung aus Deutsch)
(...) Normalerweise kümmert man sich nicht, ob ein Schlüssel (sic!) neu eingefügt oder bereits vor dem Aufruf von
insert()
(...) existierte
Welche, so scheint mir, nur für Satz gilt, und nicht für Karte, denn für eine Karte macht es einen großen Unterschied, ob der angegebene Wert eingefügt wurde oder der alte in der Karte bleibt . (Es ist egal offensichtlich nicht für den Schlüssel, wie ein Äquivalent ist.
)Hinweis: Ich weiß über operator[]
und ich weiß, über Artikel 24 des Effective STL und die dort vorgeschlagenen efficientAddOrUpdate
Funktion. Ich bin nur neugierig auf eine Begründung in insert
Semantik, weil ich persönlich finde sie gegen intuitiv.
Nun, Sie haben nicht aufgefordert, einen vorhandenen Wert zu ändern, Sie haben einen neuen Wert eingegeben. Ich stimme zu, dass ein konsequenteres Berichtsversagen eine gute Sache gewesen wäre. Sie können den zurückgegebenen Iterator immer noch dereferenzieren und prüfen, ob der neue Wert oder ein alter Wert vorhanden ist, oder diesen Iterator sogar verwenden, um den vorhandenen Wert zu aktualisieren. –
Wenn Sie ersetzen/erstellen möchten, verwenden Sie den 'operator []'. – BoBTFish
Hier ist ein Code zu ["kräftig einfügen"] (http://stackoverflow.com/a/8337563/596781) in eine Karte. –