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

try_emplace与find+insert效率对比及嵌套map用法解析

关于std::map::try_emplace的效率与嵌套map使用问题

问题背景

初始定义的结构体与map:

typedef struct st_A{
    int a = 0;
    string s;

    st_A(const int a, const string&s) :a(a),s(s) {}
}st_A;

map<string, st_A> m1;

原插入逻辑(find+insert):

if (auto it = m1.find("c1"); it == m1.end()){
    //未找到
    m1.insert({ "c1", {10, "c"} });
}else{
    // 通过it进行更新
}

改用try_emplace的实现:

auto [it, inserted] = m1.try_emplace("c1", 10, "c");
if (!inserted) {
    // 通过it进行更新
}

问题1:try_emplace确实比find+insert更高效吗?

是的,try_emplace在效率上更优:

  • find+insert的方式会两次遍历map:第一次find查找键,第二次insert执行时会再次检查键是否存在,相当于重复了一次键值查找操作。
  • try_emplace只做一次遍历:它直接定位目标键的位置,键不存在则原地构造元素,存在则直接返回指向该元素的迭代器,避免了重复查找的开销。
    此外,try_emplace能避免不必要的对象构造——如果键已存在,它不会构造st_A临时对象;而原insert写法会先构造st_A{10, "c"},哪怕最终因键存在插入失败,临时对象的构造和析构成本都会浪费。

问题2:嵌套mapmap<string, map<int, st_A>>如何正确使用try_emplace?

仍然适合用try_emplace,但需要分两步处理嵌套结构:
目标是插入pair{"c1", pair{1, st_A{10, "c"}}},即外层map键"c1"对应内层map,内层map键1对应st_A{10, "c"}。

正确实现如下:

map<string, map<int, st_A>> m2;

// 第一步:处理外层map,获取或创建键"c1"对应的内层map
auto [outer_it, outer_inserted] = m2.try_emplace("c1");
// outer_it->second 就是内层的map<int, st_A>

// 第二步:向内层map插入元素,同样用try_emplace
auto [inner_it, inner_inserted] = outer_it->second.try_emplace(1, 10, "c");

if (!inner_inserted) {
    // 如果内层元素已存在,通过inner_it更新
}

解释:

  • 外层try_emplace("c1")会在键"c1"不存在时,默认构造一个空的map<int, st_A>,无需额外参数。
  • 拿到内层map后,再对它调用try_emplace,传入内层键1和st_A的构造参数10, "c",就能原地构造目标元素,避免不必要的临时对象。

你之前尝试的m1.try_emplace("c1", 1, 10, "c")不合法,是因为外层map的值类型是map<int, st_A>,而传入的1,10,"c"无法匹配map<int, st_A>的构造函数,因此需要分两步操作嵌套结构。


内容的提问来源于stack exchange,提问作者f1msch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 21:01:44