【问题标题】:Does the standard library have a comparator reversal mechanism?标准库是否有比较器反转机制?
【发布时间】:2017-01-27 09:27:07
【问题描述】:

我知道标准库有std::reverse_iterator<...>,给定一个迭代器类型,可以用来获取它的反向(类型)。

它是否也有类似的机制来反转用于排序/排序的比较器?采用比较器类型并产生与相反顺序相对应的比较器的东西(假设顺序是可逆的)?例如 std::reverse_comparator<std::greater<int>> 等同于 std::less<int>?

【问题讨论】:

  • std::reverse_comparator<std::greater<int>> 应该是std::less_equal<int>,不是吗?
  • @EdgarRokyan:不,我不这么认为。否则为什么要用std::less 而不是std::less_equal 作为原始比较器?
  • @einpoklum 我同意埃德加的观点。如果您的比较器反转的目的是全面反转,即所有真实的现在都是虚假的,而所有虚假的现在都是真实的,那么埃德加是完全正确的。 std::greater严格更大。与此相反,所有严格大于,即所有小于相等。
  • @WhozCraig:查看我的编辑。我对您将用于排序的内容感兴趣;也许这让我更清楚为什么我不只想要return not original_comparator(x,y);
  • @einpoklum 我明白了。要颠倒顺序,您希望倒置的比较器能够实现这一点。虽然这在高层次上是有道理的,但埃德加的观点(我认为)只是我放大的。在处理需要严格弱排序的事情时,反转比较器并非易事。对于您的问题,我不认为 std lib 提供了这样的东西,尽管构建一个特定于您的反转需求的东西似乎是一项相当微不足道的任务。

标签: c++ templates iterator comparator c++-standard-library


【解决方案1】:

C++17 引入了 std::not_fn,它将 “替换” std::greater<int>std::less_equal<int>

这不是std::sort/std::map 的正确比较器。

在 std 中的其他部分,我认为不存在将其 “转换”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

【讨论】:

    【解决方案2】:

    not2,它将生成输入函子的二进制补码。但是,std::greater&lt;T&gt; 的补码不等同于std::less&lt;T&gt;,而是std::less_equal&lt;T&gt;,这对于大多数标准算法来说不是一个有效的比较器。 C++17 将引入一个通用的not_fn,它也适用于非二进制函子。

    std::less&lt;T&gt; -> std::greater&lt;T&gt; 没有开箱即用的解决方案,但应该可以实施。也许:

    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));
        };
    }
    

    【讨论】:

    • 请注意,std::not2 在 C++17 中已弃用(取而代之的是 std::not_fn)。
    • 是的,以后不需要了。不过,这个花哨的逆变器并不能转化为任意数量。
    猜你喜欢
    • 2011-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-24
    • 2011-05-16
    • 1970-01-01
    • 2019-12-29
    • 2016-01-04
    相关资源
    最近更新 更多