#include <iostream>
#include <unordered_set>
#include <set>
#include <string>
class Person {
public:
std::string name;
int age;
Person(std::string name, int age) : name(name), age(age) {}
friend struct std::hash<Person>;
size_t operator()(const Person &p) const {
size_t hash_name = std::hash<std::string>{}(p.name);
size_t hash_age = std::hash<int>{}(p.age);
return hash_name ^ hash_age;
}
// 作为unordered_set中元素需要使用operator==重载以及hansh函数
bool operator==(const Person &other) const {
return name == other.name && age == other.age;
}
// 作为set中的元素需要使用operator<重载 注意不要忘了两个const
bool operator<(const Person &other) const {
if (name == other.name) {
return age < other.age;
}
return name < other.name;
}
};
// 注意要实现这个
namespace std {
template<>
struct hash<Person> {
size_t operator()(const Person &p) const {
return p(p);
}
};
}
int main() {
std::unordered_set<Person> people_unordered;
people_unordered.insert(Person("Alice", 30));
people_unordered.insert(Person("Bob", 25));
people_unordered.insert(Person("Alice", 30));
std::set<Person> people_ordered;
people_ordered.insert(Person("Alice", 30));
people_ordered.insert(Person("Bob", 25));
people_ordered.insert(Person("Alice", 30));
std::cout << "Unordered Set:" << std::endl;
for (const auto &person: people_unordered) {
std::cout << person.name << " - " << person.age << std::endl;
}
std::cout << "\nOrdered Set:" << std::endl;
for (const auto &person: people_ordered) {
std::cout << person.name << " - " << person.age << std::endl;
}
return 0;
}
上述实现hash有一种写法,下面给出第二种写法
#include <iostream>
#include <unordered_set>
#include <string>
class MyData {
private:
int id;
std::string name;
public:
MyData(int _id, const std::string &_name) : id(_id), name(_name) {}
friend struct MyDataHash;
bool operator==(const MyData &other) const {
return (id == other.id) && (name == other.name);
}
friend std::ostream &operator<<(std::ostream &os, const MyData &data) {
os << "ID: " << data.id << ", Name: " << data.name;
return os;
}
};
struct MyDataHash {
size_t operator()(const MyData &data) const {
return std::hash<int>()(data.id) ^ std::hash<std::string>()(data.name);
}
};
int main() {
std::unordered_set<MyData, MyDataHash> mySet;
mySet.insert(MyData(1, "Alice"));
mySet.insert(MyData(2, "Bob"));
mySet.insert(MyData(1, "Alice"));
for (const auto &data: mySet) {
std::cout << data << std::endl;
}
return 0;
}