如何在unordered_map中递增int?嵌套unordered_map未递增原因解析
嘿,让我来帮你梳理这两个关于C++ unordered_map的问题,都是日常开发里很容易碰到的点~
针对这个需求,有几种常用的实现方式,按需选择就行:
最简洁的方式:直接使用[]操作符
unordered_map的[]操作符会自动处理key不存在的情况——如果key没找到,它会默认构造一个int值(也就是0),然后你直接对它递增即可。代码示例:#include <unordered_map> using namespace std; int main() { unordered_map<string, int> count_map; // 对已存在的key递增 count_map["apple"]++; // 对不存在的key,会先创建值为0的条目,再递增到1 count_map["banana"]++; return 0; }这种方式最省心,适合大多数场景。
更严谨的方式:先查找再递增
如果你不想在key不存在时自动创建条目(比如要避免不必要的内存占用),可以先用find方法查找key,找到后再对值递增:auto it = count_map.find("apple"); if (it != count_map.end()) { // 找到key,递增对应的值 it->second++; } else { // 可选:如果需要的话,在这里手动插入初始值 count_map["apple"] = 1; }C++17+的进阶方式:使用insert_or_assign
如果你想一次性处理“存在则递增,不存在则设为1”的逻辑,也可以用insert_or_assign配合查找:auto [it, inserted] = count_map.insert_or_assign("apple", 1); if (!inserted) { // 元素已存在,递增它 it->second++; }不过这种写法不如前两种直观,一般场景下用前两种就够了。
你提到的情况——首次输出1,第二次还是1,最常见的原因是你修改的是内层unordered_map的拷贝,而不是原结构中的内层map。举个例子,先看错误的写法:
#include <unordered_map> #include <iostream> using namespace std; int main() { unordered_map<int, unordered_map<string, int>> counts; // 第一次操作 auto inner_map = counts[1]; // 这里是拷贝!不是引用 inner_map["test"]++; cout << counts[1]["test"] << endl; // 输出1,因为counts[1]是新创建的条目 // 第二次操作 inner_map = counts[1]; // 又拷贝一次 inner_map["test"]++; cout << counts[1]["test"] << endl; // 还是1,修改的只是拷贝的inner_map return 0; }
问题出在auto inner_map = counts[1];这行:它把counts[1]对应的内层map拷贝了一份到局部变量inner_map里,后续对inner_map的修改只会作用在这个拷贝上,原counts里的内层map根本没被改动。
解决方法很简单:用引用绑定内层map,这样修改的就是原结构里的内容:
#include <unordered_map> #include <iostream> using namespace std; int main() { unordered_map<int, unordered_map<string, int>> counts; // 第一次操作:用引用&绑定原内层map auto& inner_map = counts[1]; inner_map["test"]++; cout << counts[1]["test"] << endl; // 输出1 // 第二次操作:直接修改引用指向的原map inner_map["test"]++; cout << counts[1]["test"] << endl; // 输出2,正常递增 return 0; }
另外还有一种小概率可能:你两次操作使用的外层/内层key不一致,但误以为是同一个。比如第一次用counts[1]["test"],第二次用了counts[2]["test"],这种情况只要检查key是否一致就能排查。
总结一下,嵌套map操作时一定要注意是否用了引用,别不小心修改了拷贝版本!
内容的提问来源于stack exchange,提问作者François

