为何C++ unordered_map::emplace()无法修改值,但operator[]可行?
问题:unordered_map的emplace与operator[]修改键值的差异原因
相关代码
#include <vector> #include <iostream> #include <algorithm> #include <string> #include <unordered_map> #include <unordered_set> using namespace std; // 双向链表 struct ListNode { int times; unordered_set<string> bucket; ListNode *prev; ListNode *next; ListNode() { prev = nullptr; next = nullptr; } ListNode(int times, string key) : ListNode() { this->times = times; bucket.emplace(key); } }; int main() { unordered_map<string, ListNode *> map; ListNode *node = new ListNode(); map.emplace("haha", node); // map["haha"] = node; ListNode *node2 = new ListNode(1, "x"); map.emplace("haha", node2); // map["haha"] = node2; }
问题详情
调用unordered_map的emplace方法两次插入键"haha",对应的值并未更新为node2的地址0xec1e20,仍为初始的0xec1c90;但使用operator[]赋值时,却能成功修改该键对应的值,请问这是什么原因?
解答
这俩方法的核心区别就是是否允许覆盖已存在的键值:
emplace的作用是插入新元素,它会先检查容器里有没有相同的键。如果键已经存在,emplace会直接跳过插入操作,完全不会修改现有键对应的值——这是为了保证unordered_map中键的唯一性,避免意外覆盖数据。operator[]则是访问或修改键对应的值:如果键不存在,它会先自动创建一个默认构造的元素(这里指针类型就是nullptr),再赋值;如果键已经存在,就直接覆盖原来的值,所以能成功更新。
如果想用类似emplace的方式同时支持插入新元素或更新现有元素,可以用C++17新增的try_emplace,或者先判断键是否存在,存在就删除旧元素再插入新的。不过日常场景中,直接用operator[]修改已存在的键值是最直接的方式。
内容的提问来源于stack exchange,提问作者Sprinining
相关产品推荐
相关产品推荐

