简体   繁体   中英

Understand the usage of `std::unordered_set`

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

struct MN
{
    MN(const int& _m, const int& _n)
        : m(_m), n(_n) {
            value = pow (m, n);
        }

    bool operator==(const MN& rhs) const {
        return m == rhs.m && n == rhs.n;
    }

    int value;      
    int m;
    int n;
};

struct MNHash
{
    size_t operator()(const MN& rhs) const {
        return hash<int>()(rhs.m) ^ hash<int>()(rhs.n);
    }
};

int main() {
    unordered_set<MN, MNHash> st;
    st.emplace(2, 3);
    st.emplace(3, 2);

    cout << st.size() << endl; // 2
    return 0;
}

Question 1> Is it true that the unordered_set uses MN::operator== to check whether the new item is duplicate or not?

Question 2> Is it true that the unordered_set uses 'MNHash' to compute the hash key of the new item?

Question 3> If the answers to both Q1 and Q2 are YES, then is it true that we will see a hash conflict in about code because both MN(2, 3) and MN(3, 2) have the same hash code?

Thank you

  1. More or less. The default comparator for std::unordered_set will use std::equal_to , which, unless specialized, will do return lhs == rhs .

    You can change this by either specializing std::equal_to , or by adding a third template argument to the std::unordered_set .

  2. It will use the second template argument to compute the hash. In this case, you've passed MNHash , so it will use that to do the work.

  3. Since the hash value of MN(2,3) and MN(3,2) are the same, they will be placed in the same bucket.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM