在下面的代码中:
#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)
不覆盖Map中的上一个实体?
5条答案
按热度按时间nnsrf1az1#
map.insert()
仅在容器尚未包含具有等效键的元素时插入。您应该改用
operator[]
:k7fdbhmy2#
在std::map::insert参考文献中指出:
如果容器尚未包含具有等效键的元素,则将元素插入容器。
kzmpq1sx3#
自C++17起更新现在有
std::map::insert_or_assign()
成员函数:顾名思义,如果键已经存在,那么值就被赋值(并且保留键对象),而不是擦除并重新复制构造键和值。(所以它相当于下面两个C++17之前的代码片段中的第一个。)
如果你想要一个迭代器指向(新的或更新的)元素,你需要再次从返回的对中选择值。
在C++17之前把其他答案放在一起,如果你想避免默认可构造的假设,你会得到如下所示的插入并覆盖代码:
在上面的代码片段中,如果元素已经存在,那么就给它赋新值。这通常是你想要的。如果你想构造而不是赋新值,但仍然想避免第二次搜索(在你擦除原始值之后),你最终会得到这个怪物:
在代码块的末尾,
it
是一个迭代器,指向刚刚插入的元素。实际上,在大多数情况下,你可能只想使用yizzlez的建议
operator[]
,但我认为最好注意理论上的最佳答案。j7dteeu84#
它不会覆盖。但是如果你检查返回值,会发现有一个
std::pair<iterator, bool>
。如果bool为true,那么它被插入了。如果bool为false,那么它因为冲突而没有被插入。此时,你可以通过写迭代器来覆盖数据。8fsztsew5#
map.insert()
只会在容器中不包含任何元素的情况下插入元素,因此这将忽略后面分配给它的值元素。