Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 插入到std::unordered_map在MSVC+中调用哈希函数两次+';是STL,糟糕的设计还是特殊原因?_C++_C++11_Visual C++_Stl - Fatal编程技术网

C++ 插入到std::unordered_map在MSVC+中调用哈希函数两次+';是STL,糟糕的设计还是特殊原因?

C++ 插入到std::unordered_map在MSVC+中调用哈希函数两次+';是STL,糟糕的设计还是特殊原因?,c++,c++11,visual-c++,stl,C++,C++11,Visual C++,Stl,对于此代码: #include<unordered_map> #include<iostream> using namespace std; struct myhash { unsigned operator()(const unsigned&v)const { cout<<"Hash function is called:"<<v<<endl; return v; } }; un

对于此代码:

#include<unordered_map>
#include<iostream>
using namespace std;
struct myhash {
    unsigned operator()(const unsigned&v)const {
        cout<<"Hash function is called:"<<v<<endl;
        return v;
    }
};
unordered_map<unsigned,unsigned,myhash>mp;
int main() {
    for (unsigned i=0;i<3;++i) {
        cout<<"Visiting hash table:"<<i<<endl;
        ++mp[i];
    }
}
但MSVC++(2015)的输出让我震惊:

Visiting hash table:0
Hash function is called:0
Hash function is called:0
Visiting hash table:1
Hash function is called:1
Hash function is called:1
Visiting hash table:2
Hash function is called:2
Hash function is called:2
进一步的测试表明,当在无序的_映射中插入新元素时,MSVC++的STL调用哈希函数两次,如果元素已经在映射中,则调用一次

我对这种行为感到非常奇怪,因为我认为在大多数情况下(如果实现确实需要使用哈希值两次),缓存结果要比再次调用哈希函数快得多。或者更好,我认为只需使用一次hash函数来查找元素的bucket,下面的例程与hash值无关


但是,由于STL的作者比C++中的我更有经验,我不知道它们是否有一些特殊的原因来实现这一点?这仅仅是一个糟糕的设计,还是由一些我不知道的原因造成的?

在发布模式下,VS2012也观察到了同样的行为

区别在于un_orderedmap的实现。 如果调试并进入:Microsoft Visual Studio 11.0\VC\include\unordered_map,则对函数调用运算符的第一个调用是检查键是否已存在于map中。
第二个调用是在insert into map期间进行的(前提是找不到密钥)-经过3次迭代后,map已经((0,1),(1,1),(2,1))

如果我们查看23.5.4.3,效果和复杂性子句似乎都不要求仅调用一次哈希函数。虽然直觉上很奇怪,但这两种实现都是合法的。

这是调试版本还是发布版本?有可能其中一个访问是为了调试目的。我似乎还记得STL(MS的标准库维护程序)提到,它们的底层机器变得更加复杂,因为它必须同时支持
unordered\u meow
和它们的非标准
hash\u meow
。我想知道这是否是由此产生的症状之一。请在打开一个bug。
Visiting hash table:0
Hash function is called:0
Hash function is called:0
Visiting hash table:1
Hash function is called:1
Hash function is called:1
Visiting hash table:2
Hash function is called:2
Hash function is called:2