我有一个std :: map将const char*
键与int
值相关联:
std::mapmyMap;
我用三个键初始化它,然后检查它是否可以找到它:
myMap["zero"] = 0; myMap["first"] = 1; myMap["second"] = 2; if (myMap.at("zero") != 0) { std::cerr << "We have a problem here..." << std::endl; }
什么都没打印出来.从这里,一切看起来都不错.
但是后来在我的代码中,没有对此地图进行任何更改,我尝试再次找到一个键:
int value = myMap.at("zero");
但该at
函数抛出std::out_of_range
异常,这意味着它无法找到该元素.myMap.find("zero")
认为是一样的,因为它在地图的末尾返回一个迭代器.
但最棘手的部分是关键是真的在地图中,如果在调用at
函数之前,我打印地图的内容如下:
for (auto it = myMap.begin(); it != myMap.end(); it++) { std::cout << (*it).first << std::endl; }
输出如预期:
零
第一
秒
怎么可能呢?我不使用任何beta测试库或任何应该不稳定的东西.
你有一个指向字符的指针映射,而不是字符串.地图查找基于指针值(地址)而不是指向的值.在第一种情况下,如果在映射中找到"零",则编译器已执行一些字符串合并,并且对两个相同的字符串使用一个字符数组.这不是语言所必需的,但是是一种常见的优化.在第二种情况下,当找不到字符串时,这个合并还没有完成(这里的代码可能在不同的源模块中),因此地图中使用的地址与插入的地址不同,然后找不到.
要解决这个问题,要么在地图中存储std :: string对象,要么在地图声明中指定比较,以便根据字符串而不是地址进行排序.