Я немного смущен семантикой std::map::insert
. Я имею в виду, я не жалуюсь - стандарт - это стандарт, и API - это так, как есть. Тем не менее,
insert
будет
выполняется операция вставки для каждого вставленного элемента. другой элемент существует уже в контейнере с тем же ключом значение, если это так, элемент не вставлен, и его отображаемое значение не является изменено каким-либо образом.
И - только в версии с одним аргументом pair<iterator,bool> insert ( const value_type& x );
он даже скажет вам, даже ли он вставил (новое, возможно другое) значение в ключ (ы). Насколько я понимаю, версии итератора молча игнорируют вставки, если ключ уже существует.
Для меня это просто счетчик интуитивно понятен, я бы ожидал, что часть значения будет перезаписана, а старая часть значения будет отброшена при вставке. Очевидно, что дизайнеры STL по-разному думали - кто-нибудь знает (историческое) обоснование или может дать полное объяснение того, как чувствует существующая семантика (больше)?
Пример:
Существует несколько основных способов реализации вставки на карте с одним ключом, например std::map
:
- вставить, заменить, если уже существует
- вставить, игнорировать, если уже существует (это поведение std:: map)
- вставить, выбросить ошибку, если она уже существует
- insert, UB, если он уже существует
Теперь я пытаюсь понять, почему insert_or_ignore
имеет больше смысла, чем insert_or_replace
(или insert_or_error
)!
Я заглянул в свою копию TС++ PL (к сожалению, у меня только немецкое издание), и, что интересно, Страуступ пишет в главе 17.4.1.7 (список операций для карты): (извините грубый перевод с немецкого)
(...) Обычно, все равно, является ли ключ (sic!) новым вставлен или уже существует до вызова
insert()
(...)
Которое, как мне кажется, справедливо только для set, а не для карты, потому что для карты это действительно имеет значение, если добавленное значение было вставлено или старый остается на карте. (Очевидно, это не важно для ключа, так как это эквивалентно.)
Примечание. Я знаю о operator[]
, и я знаю о 24-м элементе Эффективный STL и предлагаемую функцию efficientAddOrUpdate
. Мне просто интересно узнать о семантике insert
, потому что я лично считаю, что они противоречат интуитивному.