Чтобы объект можно было использовать в качестве ключа в ассоциативных контейнерах (
std::set, std::map, std::unordered_set, std::unordered_map), он должен обладать определёнными свойствами, которые зависят от типа контейнера.🚩Требования к объекту-ключу
🟠Для `std::map` и `std::set` (красно-чёрное дерево)
Класс или структура, используемая в качестве ключа, должна поддерживать операцию
< (меньше). #include <iostream>
#include <map>
struct Person {
std::string name;
int age;
// Оператор сравнения, необходимый для std::map и std::set
bool operator<(const Person& other) const {
return age < other.age; // Ключи будут упорядочены по возрасту
}
};
int main() {
std::map<Person, std::string> people;
people[{ "Alice", 30 }] = "Doctor";
people[{ "Bob", 25 }] = "Engineer";
for (const auto& [key, value] : people) {
std::cout << key.name << " (" << key.age << "): " << value << '\n';
}
}
🟠Для `std::unordered_map` и `std::unordered_set` (хеш-таблица)
Объект-ключ должен поддерживать операции:
Оператор
== (для проверки равенства)Функция-хешер (по умолчанию
std::hash<T>)#include <iostream>
#include <unordered_map>
struct Person {
std::string name;
int age;
// Оператор равенства нужен для сравнения ключей
bool operator==(const Person& other) const {
return name == other.name && age == other.age;
}
};
// Специализация std::hash для структуры Person
namespace std {
template <>
struct hash<Person> {
std::size_t operator()(const Person& p) const {
return std::hash<std::string>()(p.name) ^ (std::hash<int>()(p.age) << 1);
}
};
}
int main() {
std::unordered_map<Person, std::string> people;
people[{ "Alice", 30 }] = "Doctor";
people[{ "Bob", 25 }] = "Engineer";
for (const auto& [key, value] : people) {
std::cout << key.name << " (" << key.age << "): " << value << '\n';
}
}
Ставь 👍 и забирай 📚 Базу знаний