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