关于c ++:与map和unordered_map相关的编译错误:“试图引用已删除的函数”

Compilation error related to map and unordered_map: “attempting to reference a deleted function”

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

1
2
3
4
5
6
7
8
9
10
11
#include <vector>
#include <map>
#include <unordered_map>

using namespace std;

int main(void)
{
    unordered_map<vector<char>, int> mp;
    return 0;
}

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

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

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

1
2
3
4
5
6
7
8
9
10
11
#include <vector>
#include <map>
#include <unordered_map>

using namespace std;

int main(void)
{
    map<vector<char>, int> mp;
    return 0;
}

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


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


继@ JohnZwinck的(优秀)答案之后,我会说使用std::unordered_mapvector作为关键字通常是一个坏主意,因为实现任何类型的有效散列函数的成本可能很高。

John提供的链接对此进行了扩展,但实际上,每次需要对任何内容进行哈希处理时,哈希函数都必须检查向量中的每个元素。如果矢量很大,那么,哎哟!

所以std::map在这里可能是更好的选择,因为std::less( - > operator<)可能很便宜 - 只要我们点击两个操作数之间值不同的向量元素,我们就是完成。最糟糕的情况是,它并不昂贵(虽然确实存在廉价且有效的散列函数时std::unordered_mapstd::map更有效,特别是,例如,如果密钥类似于int)。