Написание собственного компаратора для карты C ++, которая имеет пользовательский ключ - PullRequest
0 голосов
/ 04 октября 2018

Я пытаюсь написать собственный компаратор для карты C ++, в которой есть пользовательский ключ.

struct key { int year; int no; };
map<key, detail, compare> details_map;

Если значения year равны, он должен сравнивать значения no.

Я пытаюсь найти способ написать компаратор, который может сравнивать оба значения.Пока я могу написать только компаратор, который сравнивает одно значение.

struct Compare{bool operator()(const key &lhs,const key &rhs)const{return lhs.year<rhs.year;}}

Может кто-нибудь объяснить, как работает компаратор в map?

Также возможно ли написать компаратор как функцию?

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

std::tie допускает простое лексикографическое сравнение:

struct Compare {
    bool operator()(const key& lhs, const key& rhs) const {
        return std::tie(lhs.year, lhs.no) < std::tie(rhs.year, rhs.no);
    }
};

Метод / функция as_tuple может быть интересно избежать некоторых повторений:

struct key { int year; int no; };

auto as_tuple(const key& k) { return std::tie(k.year, k.no); }

struct Compare {
    bool operator()(const key& lhs, const key& rhs) const {
        return as_tuple(lhs) < as_tuple(rhs);
    }
};
0 голосов
/ 04 октября 2018

Внутри operator() просто сравните значения no, если значения year равны:

struct Compare {
    bool operator()(const key &lhs, const key &rhs) const {
        if (lhs.year == rhs.year) {
            return lhs.no < rhs.no;
        }
        return lhs.year < rhs.year;
    }
};

И да, компаратор может быть реализован как отдельная функция:

bool Compare (const key &lhs, const key &rhs) {
    if (lhs.year == rhs.year) {
        return lhs.no < rhs.no;
    }
    return lhs.year < rhs.year;
}

В качестве альтернативы вы можете использовать компаратор std::tie() для сравнения ваших ключевых полей.См. Ответ @ Jarod42.

Тем не менее, было бы более разумно использовать вместо этого operator< для вашего key типа:

struct key {
    int year;
    int no;

    bool operator<(const key &rhs) const {
        if (year == rhs.year) {
            return no < rhs.no;
        }
        return year < rhs.year;
    }
};

Или

struct key {
    int year;
    int no;
};

bool operator<(const key &lhs, const key &rhs) {
    if (lhs.year == rhs.year) {
        return lhs.no < rhs.no;
    }
    return lhs.year < rhs.year;
}

Тогда вам не нужен отдельный компаратор:

map<key, detail> details_map;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...