You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 21:33:18