Ответ
Класс или структура могут быть использованы в качестве ключа std::set, если для них определен строгий слабый порядок (Strict Weak Ordering). Это достигается одним из двух способов:
- Определение оператора
<для типа ключа. - Предоставление пользовательского функтора-компаратора в качестве второго шаблонного параметра
std::set.
Пример 1: Использование оператора <
struct Point {
int x, y;
// Определяем порядок: сначала по x, затем по y
bool operator<(const Point& other) const {
return std::tie(x, y) < std::tie(other.x, other.y);
}
};
std::set<Point> points; // Корректно, используется operator<
Пример 2: Использование пользовательского компаратора
struct Person {
std::string name;
int age;
};
// Компаратор, сравнивающий только по возрасту
struct CompareByAge {
bool operator()(const Person& a, const Person& b) const {
return a.age < b.age;
}
};
std::set<Person, CompareByAge> people;
// В этом set нельзя будет иметь двух людей с одинаковым возрастом.
Критические требования к компаратору (Compare):
- Антисимметричность: Если
comp(a, b) == true, тоcomp(b, a) == false. - Транзитивность: Если
comp(a, b) == trueиcomp(b, c) == true, тоcomp(a, c) == true. - Транзитивность эквивалентности: Если
!comp(a, b) && !comp(b, a)(эквивалентны) и!comp(b, c) && !comp(c, b), то!comp(a, c) && !comp(c, a).
Без выполнения этих условий поведение std::set не определено (UB).