问题 为什么我不能使用pair作为unordered_set / unordered_map的键? [重复]


这个问题在这里已有答案:


6937
2018-05-24 03:06


起源



答案:


unordered_* 容器需要哈希函数。默认情况下,他们使用 std::hash 但没有专业化 std::hash 对于 std::pair<T1,T2> 在标准库中提供。另一方面, 有序 容器依赖 std::less (默认情况下)和 std::pair   有 operator< 提供。这就是为什么它才有效。

为了有一个无序的容器 pair,你必须自己提供一个哈希仿函数。例如:

struct SimpleHash {
    size_t operator()(const std::pair<int, int>& p) const {
        return p.first ^ p.second;
    }
};

std::unordered_set<std::pair<int, int>, SimpleHash> S;
S.insert(std::make_pair(0, 1));

16
2018-05-24 03:09



S.emplace(......也可以,如果没有,你会改变什么? - HeinrichStack
@Barry可以p.first ^ p.second获得p_a和p_b等不同对的相同值吗? - olivia
@olivia当然。它肯定会给你相同的价值 (a,b) 和 (b,a)。它不是一个完美的哈希函数,只是一个简单的例子。 - Barry


答案:


unordered_* 容器需要哈希函数。默认情况下,他们使用 std::hash 但没有专业化 std::hash 对于 std::pair<T1,T2> 在标准库中提供。另一方面, 有序 容器依赖 std::less (默认情况下)和 std::pair   有 operator< 提供。这就是为什么它才有效。

为了有一个无序的容器 pair,你必须自己提供一个哈希仿函数。例如:

struct SimpleHash {
    size_t operator()(const std::pair<int, int>& p) const {
        return p.first ^ p.second;
    }
};

std::unordered_set<std::pair<int, int>, SimpleHash> S;
S.insert(std::make_pair(0, 1));

16
2018-05-24 03:09



S.emplace(......也可以,如果没有,你会改变什么? - HeinrichStack
@Barry可以p.first ^ p.second获得p_a和p_b等不同对的相同值吗? - olivia
@olivia当然。它肯定会给你相同的价值 (a,b) 和 (b,a)。它不是一个完美的哈希函数,只是一个简单的例子。 - Barry


您需要为pair提供哈希函数。


0
2018-05-24 03:08