与map和unordered_map相关的编译错误:"尝试引用已删除的函数"

FS.*_*S.L 6 c++ c++11

我想在C++ STL中使用map来创建vector和int之间的关联.但是我得到了多个编译错误,代码如下:

#include <vector>
#include <map>
#include <unordered_map>

using namespace std;

int main(void)
{
    unordered_map<vector<char>, int> mp;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

并在VC++中得到此编译错误:

错误C2280:'std :: hash <_Kty> :: hash(const std :: hash <_Kty>&)':尝试引用已删除的函数

但是,如果我改变我的代码,如下所示,那么代码可以正确编译:

#include <vector>
#include <map>
#include <unordered_map>

using namespace std;

int main(void)
{
    map<vector<char>, int> mp;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我在StackoverFlow中发现了这个问题,其标题是:使用自定义类类型作为键的C++ unordered_map.但我想知道为什么使用map <>可以通过编译检查但无法使用unordered_map <>?

Joh*_*nck 10

map要求实施小于比较.它是一个矢量.但unordered_map需要哈希函数,您需要自己实现.这不是什么大问题,你可以hash_combine在这里看到如何使用它:`std :: vector`的快速哈希函数


Pau*_*ers 6

根据@JohnZwinck(优秀)的回答,我想说,使用std::unordered_mapavector作为键通常是一个坏主意,因为实现任何类型的有效散列函数的成本可能很高。

约翰给出的链接对此进行了扩展,但本质上,每次需要散列任何内容时,散列函数都必须检查向量中的每个元素。如果向量很大,那么,哎呀!

所以std::map在这里可能是更好的选择,因为std::less(-> operator<) 可能很便宜 - 一旦我们遇到两个操作数之间值不同的向量元素,我们就完成了。最坏的情况下,它并不更昂贵(尽管确实比存在廉价且有效的散列函数时std::unordered_map更有效std::map,特别是,例如,如果键是类似于 a 的东西int)。