我有一个std :: map将index.html
个关键字与const char*
值相关联:
int
我用三个键初始化它,然后检查它是否能找到它:
std::map<const char*, int> myMap;
没有打印出来。从这里开始,一切看起来都不错。
但是后来在我的代码中,没有对此地图进行任何更改,我尝试再次找到一个键:
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
输出符合预期:
零
第一
第二
怎么可能呢?我没有使用任何beta测试库或任何应该不稳定的东西。
答案 0 :(得分:8)
你有一个指向字符的指针映射,而不是字符串。地图查找基于指针值(地址)而不是指向的值。在第一种情况下,如果在映射中找到“零”,则编译器已执行一些字符串合并,并且对两个相同的字符串使用一个字符数组。这不是语言所必需的,但是是一种常见的优化。在第二种情况下,当找不到字符串时,这个合并还没有完成(这里的代码可能在不同的源模块中),因此地图中使用的地址与插入的地址不同,然后找不到
要修复此问题,请在地图中存储std :: string对象,或在地图声明中指定比较,以便根据字符串而不是地址进行排序。
答案 1 :(得分:1)
地图的关键是char *
。因此,映射比较函数将尝试比较原始指针值而不是c样式字符串等效性检查。因此,请声明以std::string
为键的地图。
如果您不想处理std::string
并且仍然希望具有相同的功能并提高时间复杂度,那么复杂的数据结构就是完整的。看看像Judy Array这样的一些实现。