我使用英特尔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/