标准库有比较器反转机制吗?
Does the standard library have a comparator reversal mechanism?
我知道标准库有std::reverse_iterator<...>
,给定一个迭代器类型,它可以用来获取它的反向(类型)。
它是否也有类似的机制来反转用于 sorting/ordering 的比较器?采用比较器类型并产生与相反顺序相对应的比较器的东西(假设顺序是可逆的)?例如
std::reverse_comparator<std::greater<int>>
等同于 std::less<int>
?
C++17 引入了 std::not_fn
,它将 "replace" std::greater<int>
by std::less_equal<int>
.
这不是 std::sort
/std::map
的正确比较器。
Else 在 std 中,我不认为它存在 "transform" 到 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;
};
有not2
,它会生成输入函子的二进制补码。但是,std::greater<T>
的补码并不等同于 std::less<T>
,而是 std::less_equal<T>
,它不是大多数标准算法的有效比较器。 C++17 将引入一个泛型 not_fn
,它也适用于 non-binary 函子。
std::less<T>
-> std::greater<T>
没有开箱即用的解决方案,但应该可以实施。也许:
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::reverse_iterator<...>
,给定一个迭代器类型,它可以用来获取它的反向(类型)。
它是否也有类似的机制来反转用于 sorting/ordering 的比较器?采用比较器类型并产生与相反顺序相对应的比较器的东西(假设顺序是可逆的)?例如
std::reverse_comparator<std::greater<int>>
等同于 std::less<int>
?
C++17 引入了 std::not_fn
,它将 "replace" std::greater<int>
by std::less_equal<int>
.
这不是 std::sort
/std::map
的正确比较器。
Else 在 std 中,我不认为它存在 "transform" 到 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;
};
有not2
,它会生成输入函子的二进制补码。但是,std::greater<T>
的补码并不等同于 std::less<T>
,而是 std::less_equal<T>
,它不是大多数标准算法的有效比较器。 C++17 将引入一个泛型 not_fn
,它也适用于 non-binary 函子。
std::less<T>
-> std::greater<T>
没有开箱即用的解决方案,但应该可以实施。也许:
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));
};
}