C++17中如何在嵌套map中使用emplace/insert_or_assign?
解决嵌套map用emplace/insert_or_assign的简洁写法
针对嵌套map插入时重复书写内层类型的问题,以下是几种简洁的实现方式:
1. 利用C++17的类模板参数推导(CTAD)
这是最直观的简化方案,编译器会自动推导内层std::map的模板参数,无需显式写出map<int, int>这类完整类型:
- 两层嵌套map的写法:
map<int, map<int, int>> m; // 使用emplace m.emplace(1, std::map{{1, 1}}); // 使用insert_or_assign m.insert_or_assign(1, std::map{{1, 1}}); - 四层嵌套的场景下,写法会更简洁,完全不用逐层声明模板参数:
map<int, map<int, map<int, map<int, int>>>> m; m.emplace(1, std::map{{2, std::map{{3, std::map{{4, 5}}}}}});
2. 使用std::piecewise_construct构造(C++11及以上)
如果项目仍在使用C++11/14(不支持CTAD),可以用piecewise_construct配合forward_as_tuple,直接在emplace时构造内层map,避免显式声明内层类型:
map<int, map<int, int>> m; m.emplace( std::piecewise_construct, std::forward_as_tuple(1), // 外层map的键 std::forward_as_tuple(std::initializer_list<std::pair<const int, int>>{{1, 1}}) // 内层map的初始化列表 );
多层嵌套时,内层的forward_as_tuple里可继续嵌套初始化列表,同样无需写内层map的完整类型。
补充说明
emplace和operator[]的区别:operator[]会先默认构造空的内层map(若键不存在)再赋值;emplace则直接构造目标内层map,避免了默认构造的额外开销。insert_or_assign和emplace的区别:emplace仅在键不存在时插入新元素;insert_or_assign无论键是否存在,都会将对应值替换为新构造的内层map,适合需要覆盖旧值的场景。
内容的提问来源于stack exchange,提问作者f1msch
相关产品推荐
相关产品推荐

