c++ - 使用std::map应该是确定性的吗?

标签 c++ stl visual-studio-2019 icc

我使用英特尔C++编译器2019更新5时遇到一种奇怪的行为。当我填写std::map时,似乎会导致不确定的(?)结果。 STL来自VS2019 16.1.6,其中嵌入了ICC。我在Windows 10.0.17134.286上。

我的代码:

#include <map>
#include <vector>
#include <iostream>

std::map<int, int> AddToMapWithDependencyBetweenElementsInLoop(const std::vector<int>& values)
{
    std::map<int, int>  myMap;
    for (int i = 0; i < values.size(); i+=3)
    {
        myMap.insert(std::make_pair(values[i], myMap.size()));
        myMap.insert(std::make_pair(values[i + 1], myMap.size()));
        myMap.insert(std::make_pair(values[i + 2], myMap.size()));
    }
    return myMap;
}

std::map<int, int> AddToMapOnePerLoop(const std::vector<int>& values)
{
    std::map<int, int>  myMap;
    for (int i = 0; i < values.size(); ++i)
    {
        myMap.insert(std::make_pair(values[i], 0));
    }
    return myMap;
}

int main()
{
    std::vector<int> values{ 6, 7,  15, 5,  4,  12, 13, 16, 11, 10, 9,  14, 0,  1,  2,  3,  8,  17 };

    {
        auto myMap = AddToMapWithDependencyBetweenElementsInLoop(values);
        for (const auto& keyValuePair : myMap)
        {
            std::cout << keyValuePair.first << ", ";
        }
        std::cout << std::endl;
    }

    {
        auto myMap = AddToMapOnePerLoop(values);
        for (const auto& keyValuePair : myMap)
        {
            std::cout << keyValuePair.first << ", ";
        }
        std::cout << std::endl;
    }

    return 0;
}

我只是想执行一个测试,所以我从命令行直接调用icl:
$ icl /nologo mycode.cpp
$ mycode.exe
0, 1, 2, 3, 4, 5, 6, 7, 11, 12, 13, 14, 15, 16, 17,
0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 16, 17

好奇。我预计会有18个条目,而我只有15个和14个(取决于插入方法,请参见代码)。
$ icl /nologo /EHsc mycode.cpp
$ mycode.exe
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17,
0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 16, 17

仍然很好奇,现在我得到了17和14个条目,而不是18和18个!
$ icl /nologo /Od mycode.cpp
$ mycode.exe
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,

现在,没有优化,我得到了预期的18/18。

我的问题有两个:1)得到这样的结果正常吗?2)如果不是(我怀疑)我做错了什么?我对编译器的简单调用会正确调用std::map::insert()函数吗?

问题是否出在for(){}上?

感谢您帮助我理解此问题并找到解决方案!

最佳答案

我无法重现此内容,但无论哪种情况,为了让您安心,您可以将 map 填充得更加简单:

  for (auto i: values) {
    myMap[i] = 0;
  }
无需仅使用myMap.insert(std::make_pair(key, value))将条目添加到 map 。
否则,您的代码会产生预期的输出(0、1、2、3、4、5、6、7、8、9、10、11、12、13、14、15、16、17两次,该序列显然已排序因为这是有序映射)(如果在Ubuntu下使用gcc 8.4.0编译)。我怀疑这只是您使用的特定编译器的错误。将错误报告给编译器开发人员以便他们可以修复它将是有益的。

关于c++ - 使用std::map应该是确定性的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58845595/

相关文章:

c++ - C++中的哈希表/无序映射

c++ - 管理指针 vector 和对象 vector 的模板类

c# - 泛型阻止虚函数调用?

visual-studio - Visual Studio 无需重建代码即可查看 html 更改

c++ - _mm_cvtsd_f64 模拟高阶 float

c++ - strcpy 没有在此范围内声明?

c++ - 检测多字节字符编码

c++ - 使用自定义比较器函数在类中定义优先级队列

c++ - 除非整行相同,否则正则表达式不匹配

visual-studio-2019 - 是否有 Visual Studio 2019 组合解决方案的方法?