2017-01-27 14 views
3

Я знаю, что стандартная библиотека имеет std::reverse_iterator<...>, которая, учитывая тип итератора, может быть использована для получения ее обратного (типа).Имеет ли стандартная библиотека механизм разворота компаратора?

Имеет ли он аналогичный механизм для реверсирования компараторов, используемых для сортировки/заказа? Что-то, что принимает тип компаратора и производит компаратор, соответствующий обратному порядку (при условии, что порядок обратим)? например с std::reverse_comparator<std::greater<int>> эквивалентно std::less<int>?

+1

'станд :: reverse_comparator <станд :: больше >' 'должны быть станд :: less_equal ', не так ли? –

+0

@EdgarRokyan: Нет, я так не думаю. Иначе почему вместо std :: less_equal 'std :: less' вместо исходного? – einpoklum

+1

@einpoklum Я согласен с Эдгаром. Если целью вашего разворачивания компаратора является полная инверсия, т. Е. Все, что было истинно, теперь ложно, а все, что было ложным, теперь истинно, то Эдгар точно прав. 'std :: greater' * строго * больше. Обратное к этому было бы * не * строго-большим, что все равно меньше или равно. – WhozCraig

ответ

4

C++ 17 вводит std::not_fn, который "заменить"std::greater<int> по std::less_equal<int>.

который является неправильным компаратом для std::sort/std::map.

Else в станд, я не думаю, что существует один, который "трансформировать" в std::less<int>, но вы можете написать свой собственный легко, что-то вроде:

template <typename Comparer> 
struct InvComparer 
{ 
public: 
    explicit InvComparer(Comparer comparer) : comp(comparer) {} 
    template <typename T1, typename T2> 
    bool operator() (const T1& lhs, const T2& rhs) const { return comp(rhs, lhs); }; 
private: 
    Comparer comp; 
}; 

Demo

1

Eсть not2, который будет генерировать двоичный компонент входного функтора. Однако дополнение std::greater<T> не эквивалентно std::less<T>, но std::less_equal<T>, что не является допустимым компаратором для большинства стандартных алгоритмов. C++ 17 собирается ввести общий not_fn, который также работает с не двоичными функторами.

Для std::less<T> 0 0 нет. Возможно:

template<class Pred> 
auto 
fancy_not2(Pred&& pred) { 
    return [pred=std::forward<Pred>(pred)](auto&& left, auto&& right){ 
     return left != right 
      && !pred(std::forward<decltype(left)>(left), 
        std::forward<decltype(right)>(right)); 
    }; 
} 
+0

Обратите внимание, что 'std :: not2' устарел на C++ 17 (в пользу' std :: not_fn'). – Jarod42

+0

Да, в будущем больше нет необходимости. Тем не менее, этот фантастический инвертор не переводит на произвол. – user2079303