Ответ
Для использования пользовательского типа (например, структуры) в качестве ключа std::map<K, V> необходимо обеспечить для этого типа строгое слабое упорядочивание (strict weak ordering). На практике это означает, что должен быть определен способ сравнения двух ключей на «меньше».
Способ 1: Перегрузка оператора < внутри структуры (наиболее распространённый).
#include <map>
struct Point {
int x, y;
// Ключевые моменты: метод const, параметр const&
bool operator<(const Point& other) const {
// Лексикографическое сравнение (сначала по x, затем по y)
if (x != other.x) return x < other.x;
return y < other.y;
}
};
int main() {
std::map<Point, std::string> labelMap;
labelMap[{1, 2}] = "Start";
labelMap[{3, 4}] = "End";
// map автоматически использует перегруженный operator<
return 0;
}
Способ 2: Создание внешнего функционального объекта (компаратора) и передача его в map.
struct Point { int x, y; };
struct PointComparator {
bool operator()(const Point& a, const Point& b) const {
return std::tie(a.x, a.y) < std::tie(b.x, b.y);
}
};
int main() {
// Явно указываем компаратор как третий шаблонный параметр
std::map<Point, std::string, PointComparator> mapWithCustomComparator;
}
Важно: Если оператор сравнения не обеспечивает строгого слабое упорядочивание (например, если для разных точек a и b оба a < b и b < a ложны, но точки не равны), поведение std::map будет неопределённым.