c++ - std::map 迭代 - 调试和发布版本之间的顺序差异

标签 c++ stl

这是我必须使用的一个通用代码模式:

class foo {
public:
    void InitMap();
    void InvokeMethodsInMap();
    static void abcMethod();
    static void defMethod();
private:
    typedef std::map<const char*, pMethod> TMyMap;
    TMyMap m_MyMap;
}

void
foo::InitMap()
{
    m_MyMap["abc"] = &foo::abcMethod;
    m_MyMap["def"] = &foo::defMethod;
}

void
foo::InvokeMethodsInMap()
{
    for (TMyMap::const_iterator it = m_MyMap.begin();
        it != m_MyMap.end(); it++)
    {
        (*it->second)(it->first);
    }
}

但是,我发现处理 map 的顺序(在 for 循环内)可能会根据构建配置是 Release 还是 Debug 而有所不同。似乎发布版本中发生的编译器优化会影响此顺序。

我认为通过在上面的循环中使用 begin() 并在每次方法调用后递增迭代器,它会按初始化顺序处理映射。但是,我还记得读过一个 map 是作为哈希表实现的,无法保证顺序。

这特别烦人,因为大多数单元测试都是在调试版本上运行的,并且通常直到外部 QA 团队开始测试(因为他们使用发布版本)才会发现奇怪的顺序依赖错误。

谁能解释这种奇怪的行为?

最佳答案

不要使用 const char*作为 map 的关键。这意味着映射是按字符串的地址而不是字符串的内容排序的。使用 std::string作为键类型,而不是。

std::map不是哈希表,它通常实现为红黑树,并且元素保证按某些标准排序(默认情况下,< 键之间的比较)。

关于c++ - std::map 迭代 - 调试和发布版本之间的顺序差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/137258/

相关文章:

C++ 如何将对象指针发送到函数(对指针列表进行排序)

c++ - 用户定义和标准转换

java - 将cpp文件添加到cocos2d-x项目android项目

c++ - 类型 'long long int' 到二进制 'operator%' 的无效操作数

c++ - 有析构函数为什么会生成拷贝构造函数

c++ - 在 OpenCV 中合并两个 Mat 对象

C++,实例化 std::vector 时性能不佳

c++ - 保留容量会导致两次分配还是一次分配?

c++ - 如何使用可变参数模板使用 std::function

c++ - 为什么 std::move 表现得像 std::copy?