c++ - 为什么 unordered_set 的元素对于自定义 equal_to 不是唯一的

标签 c++ stl unordered-set

我试图更好地理解 unordered_set。主要是,根据我的理解,unordered_set 中的元素在 equal_to 运算符之前应该是唯一的。 因此,我决定通过一小段代码来测试一下

#include <iostream>
#include <unordered_set>
using namespace std;

struct m_int
{
    int x;
};
// template specialization for std::hash
template<>
struct std::hash<m_int>
{
std::size_t operator()(m_int const& x) const noexcept
{

return hash<int>{}(x.x); 
}
};
//template specialization for std::equal_to

template<>
struct std::equal_to<m_int>
{
bool operator()(const m_int &lhs, const m_int &rhs) const 
{
    
return abs(lhs.x-rhs.x)<=3;
}
};
int main() {
    unordered_set<m_int> m={{1},{2},{3},{4}};
    for(auto&x:m)
        cout<<x.x<<' ';
    cout<<endl;
    cout<<m.count({2})<<endl;
    // your code goes here
    return 0;
}

我最初的想法是 1 会插入 2,3 会插入但 4 会被插入。

我得到的输出是

4 3 2 1 
1

既然按照我的equal_to 1和2是一样的,那么这个集合实际上包含了重复,这违反了集合的定义。为什么会这样?我该如何解决?

最佳答案

无序容器 have the following requirements for their hash and key equality functions :

If two Keys are equal according to Pred, Hash must return the same value for both keys.

您的容器并非如此。例如,1 和 4 比较相等,但它们(几乎可以肯定)具有不同的哈希值。这会导致未定义的行为。

这里还有一个逻辑问题:1等于4,4等于7,但是1不等于7。这也不计算。

关于c++ - 为什么 unordered_set 的元素对于自定义 equal_to 不是唯一的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72361930/

相关文章:

c++ - 纹理的理解

c++ - 有没有办法在 C++ 基类中创建 "virtual"变量?

c++ - 为什么 [std::unique] 不能应用于 [std::multiset]?

STL vector+sort+equality vs. unordered_set vs. using pure set 的性能(内存和速度方面)

c++ - 为 unordered_set 重载 () 运算符

c++ - 在 C++ 中为 unordered_set 声明散列函数?

c++ - Wt::Http::Client 总是以 throw_exception<boost::bad_weak_ptr>() 结束

c++ - 如果在着色器中未使用绑定(bind)属性位置,是否会有惩罚?

c++ - C++中的智能数据结构可保存数据以加快访问速度

c++ - 新的 T(x, y, z) 作为函数