【问题标题】:Different behaviour with std::unordered_map container on Windows and LinuxWindows 和 Linux 上 std::unordered_map 容器的不同行为
【发布时间】:2013-09-06 13:26:31
【问题描述】:

对于我的程序,我需要无序键。为了完成工作,我使用 std::unordered_map 容器。这是一个测试代码:

#include <iostream>
#include <unordered_map>
#include <string>

int main()
{
    std::unordered_map<std::string, int> toto;

    toto["Outlook"] = 454;
    toto["Temperature"] = 4;
    toto["Humidity"] = 554;
    toto["Wind"] = 545454;

    std::unordered_map<std::string, int>::iterator It = toto.begin();

    std::cout << toto.size() << std::endl;

    for (; It != toto.end(); ++It)
        std::cout << (*It).first << std::endl;
    getchar();
    return (0);
}

在 Windows (Visual Studio 2012) 上,输出为:

Outlook
Temperature
Humidity
Wind

没错。未应用任何排序。

但在 Linux 上,输出如下:

Humidity
Outlook
Wind
Temperature

PS : 在 linux 上,我使用 -std::c++0x 和 -std=gnu++0x 编译我的程序,并且没有编译错误。

那么,同一个程序怎么可能有不同的行为呢? 提前感谢您的帮助!

【问题讨论】:

  • 它是无序的。你为什么关心订单?
  • @chris 据我所知,unordered_map 使用哈希结果作为内部容器中元素的索引。 std::unordered_map 迭代器是那个容器的迭代器,所以当你遍历 unordered_map 时,你实际上是遍历了那个内部容器。那么,不同的顺序意味着不同的哈希结果,或者不同的分配策略?
  • @Manu343726:不同的实现。不同的月相。不同数量的山羊。订单未定义,仅此而已。没有什么需要了解的了。
  • 所以你想知道为什么一个无序容器在使用不同操作系统上运行的不同编译器编译的不同实现上具有不同的顺序?

标签: c++ c++11 unordered-map


【解决方案1】:

unordered_map 通常(实际上总是读取)使用哈希表实现,默认情况下使用 std::hash 选择将项目放入哪个存储桶。

有许多不同的哈希函数,所以您看到的是,std::hash 在 Windows 和 Linux 上的两个不同标准库实现使用两个不同的哈希函数 - 它们产生不同的哈希码 - 进而产生不同的存储桶放置,因此在迭代时会出现不同的排序。

如果您不明白 hash table data structure 的含义,我一般会花一些时间来研究它。在编程的许多方面,散列是一个非常酷且有用的数学工具。

【讨论】:

  • 另外,即使是相同的hash函数和hash值,当前bucket的个数也会影响item的位置。
  • 正确,此外,两种实现可能使用不同的负载因子或冲突解决策略,这也会影响迭代顺序。
【解决方案2】:

正如名称 (unordered_map) 所暗示的 - 容器是无序的。没有人保证项目的顺序是什么以及真正的 - 每个实现都有不同的顺序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-26
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    • 2021-03-11
    相关资源
    最近更新 更多