如何区分C++ unordered_map<T, int>中不存在元素与值为0的元素
区分
unordered_map中不存在的键与值为0的已存在键 这个问题绝对是C++里使用unordered_map(包括map)时的经典“陷阱”!你遇到的核心问题是**operator[]的特殊行为**:当你用H["house"]访问一个不存在的键时,它会自动在容器里插入这个键,并给它赋一个默认值(对于int类型就是0)。所以你原来的代码里,第一次执行H["house"]的时候,不管之前有没有这个键,之后它肯定存在了,自然没法区分“本来不存在”和“值就是0”的情况。
正确的解决方法
方法1:使用find()(推荐)
find()方法会返回一个迭代器,指向找到的元素;如果键不存在,就返回H.end()。关键是它不会修改容器,完美解决你的需求:
#include <unordered_map> #include <iostream> using namespace std; int main() { unordered_map<string, int> H; auto it = H.find("house"); if (it == H.end()) { cout << "DOES NOT EXIST YET\n"; H["house"] = 0; // 现在手动插入并赋值0 } else { // 键已经存在,判断它的值 if (it->second == 0) { cout << "EXISTS AND VALUE IS 0\n"; } else { cout << "EXISTS WITH VALUE: " << it->second << "\n"; } } // 再次检查 it = H.find("house"); if (it != H.end()) { cout << "IT EXISTS NOW\n"; } return 0; }
方法2:使用count()
因为unordered_map的键是唯一的,count(key)只会返回0(不存在)或1(存在)。用它做存在性判断也很直观:
if (H.count("house") == 0) { cout << "DOES NOT EXIST YET\n"; H["house"] = 0; } else { // 确认存在后,再安全地访问值 if (H["house"] == 0) { cout << "EXISTS AND VALUE IS 0\n"; } }
为什么你的原代码不工作?
看你的示例代码:
if(!H["house"]){ cout<<"DOES NOT EXIST YET\n"; H["house"] = 0; } if(H["house"]){ cout<<"IT EXISTS NOW\n"; }
第一次执行H["house"]时,不管键存不存在,operator[]都会插入这个键并赋值0。所以第一个if的条件!H["house"](也就是!0)会成立,执行输出和赋值,但此时"house"已经在容器里了。第二个if(H["house"])的条件是0,所以永远不会触发输出——这就是问题所在。
总结
记住一个原则:永远不要用operator[]来判断键是否存在,因为它会偷偷修改你的容器。做存在性检查时,优先用find()(需要访问值时更高效)或count()(代码更简洁)。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

