什么可以使std :: map找不到它的一个键?

时间:2015-12-09 06:52:41

标签: c++ c++11 dictionary std

我有一个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测试库或任何应该不稳定的东西。

2 个答案:

答案 0 :(得分:8)

你有一个指向字符的指针映射,而不是字符串。地图查找基于指针值(地址)而不是指向的值。在第一种情况下,如果在映射中找到“零”,则编译器已执行一些字符串合并,并且对两个相同的字符串使用一个字符数组。这不是语言所必需的,但是是一种常见的优化。在第二种情况下,当找不到字符串时,这个合并还没有完成(这里的代码可能在不同的源模块中),因此地图中使用的地址与插入的地址不同,然后找不到

要修复此问题,请在地图中存储std :: string对象,或在地图声明中指定比较,以便根据字符串而不是地址进行排序。

答案 1 :(得分:1)

地图的关键是char *。因此,映射比较函数将尝试比较原始指针值而不是c样式字符串等效性检查。因此,请声明以std::string为键的地图。

如果您不想处理std::string并且仍然希望具有相同的功能并提高时间复杂度,那么复杂的数据结构就是完整的。看看像Judy Array这样的一些实现。