为什么C ++ map.insert()不会覆盖

时间:2014-10-24 14:10:06

标签: c++

在下面的代码中:

#include <map>
#include <utility>
#include <iostream>

using namespace std;

int main(){
  pair<int,int> p1(1,1);
  pair<int,int> p2(1,2);

  map<int,int> m;
  m.insert(p1);
  m.insert(p2);

  cout << "Map value: "<< m.at(1) << endl;

}

打印出来:Map value: 1,为什么m.insert(p2)不会覆盖地图中的上一个实体?

5 个答案:

答案 0 :(得分:8)

map.insert()仅在容器尚未包含具有等效键的元素时才会插入。

您应该使用operator[]代替:

 m[p2.first] = p2.second;

答案 1 :(得分:3)

std::map::insert参考文献中说:

  

如果容器尚未包含具有等效键的元素,则将元素插入容器中。

答案 2 :(得分:3)

它不会被覆盖。但是,如果您检查返回值,则会有std::pair<iterator, bool>。如果bool为true,则插入它。如果bool为假,则由于碰撞而没有插入。此时,您可以通过写入迭代器来自己覆盖数据。

答案 3 :(得分:0)

这应该发生。如果元素不包含任何元素,map.insert()只会将元素插入到容器中,因此这将忽略分配给它的后面的元素元素。

答案 4 :(得分:0)

将其他答案放在一起,如果您想避免默认可构造的假设,则会得到如下所示的覆盖插入代码:

auto itAndWasInserted = m.insert(p1);
if (!itAndWasInserted.second) {
    *(itAndWasInserted.first) = p1;
}

如果您想避免复制结构,但又想避免第二次搜寻(重新插入),则会遇到这个怪物:

auto itAndWasInserted = m.insert(p1);
auto it = itAndWasInserted.first;
if (!itAndWasInserted.second) {
    auto afterIt = m.erase(it);
    auto newItAndWasInserted = m.insert(afterIt, p1);  // Hint form of insert
    it = newItAndWasInserted.first;
}

在代码块的末尾,it是指向刚刚插入的元素的迭代器。

实际上,在大多数情况下,您可能只想使用yizzlez的建议operator[],但我认为最好注意理论上的最佳答案。