Есть ли что-нибудь для общего инвертирования типа C ++ Comparator? - PullRequest
3 голосов
/ 31 мая 2019

Например, если я передал std::less, я бы хотел, чтобы он создал новый компаратор с поведением, равным std::greater.Для использования в шаблонах.

Что-то, что включало бы синтаксис, такой как std::map<int, int, std::invert<std::less>> (за исключением того, что то, что я ищу, существует, это не то, как оно называется).Это существует?

1 Ответ

4 голосов
/ 31 мая 2019

Есть std::not_fn, , которые :

Создает упаковщик переадресации вызовов, который возвращает отрицание вызываемого объекта, который он содержит.

Однако в этом случае это приведет к компаратору с функциональностью std::greater_equal, а не std::greater. Кроме того, тип не совпадает с std::greater_equal.

Пример:

auto greater_eq = std::not_fn(std::less<>());

Для получения эквивалента std::greater вы получаете это, переключая аргументы. Я не думаю, что есть функция для этого в стандартной библиотеке, но это просто написать себе:

auto flip = [](auto fun) {
    return [fun = std::move(fun)]
           (const auto& arg1, const auto& arg2)
    {
        return fun(arg2, arg1);
    };
};

auto greater = flip(std::less<>());

Это также может быть расширено для поддержки любого количества аргументов, переворачивая только первые два (что делает его аналогичным flip от Haskell), а также для поддержки идеальной пересылки аргументов, но эти функции могут усложнить аккуратный пример совсем немного и не нужны для компараторов.

...