Как передать компаратор в std::map

Есть следующий код

typedef std::pair<double, double> Point;

bool cmp(const Point& p1,const Point& p2){
    if (p1.first != p2.first){
        return p1.first < p2.first;
    }
    return p1.second < p2.second;
}

int main() {
    std::map<Point, int> a;
}

Как передать cmp() в качестве компаратора в std::map?


Ответы (2 шт):

Автор решения: αλεχολυτ

Шаблон std::map принимает компаратор в качестве третьего параметра. Но главное здесь то, что это должен быть класс с соответствующим operator(), поэтому вместо функции надо просто создать класс:

#include <map>

typedef std::pair<double, double> Point;

struct CMP {
    bool operator()(const Point& p1, const Point& p2) const {
        if (p1.first != p2.first){
            return p1.first < p2.first;
        }
        return p1.second < p2.second;
    }
};

int main() {
    std::map<Point, int, CMP> a;
}

Подойдёт и лямбда, но параметром всё равно будет тип, хоть и порождённый лямбдой. И для инстанцирования нужно будет явно передавать экземпляр как в ответе Fat-Zer.

auto l = [](const Point& p1, const Point& p2) { 
    if (p1.first != p2.first){
        return p1.first < p2.first;
    }
    return p1.second < p2.second; 
};

int main() {
    std::map<Point, int, decltype(l)> a(l);
}
→ Ссылка
Автор решения: Fat-Zer

А если по каким-то причинам есть желание обойтись без функтора (хотя практических причин для этого я и не представляю), то можно изощриться как-то так:

std::map<Point, int, bool(*) (const Point& p1,const Point& p2)> a(cmp);

Начиная с c++11 это можно немного проще записать с помощью decltype¹:

std::map<Point, int, decltype(&cmp)> a(cmp);

¹ Спасибо @αλεχολυτ за уточнение

→ Ссылка