是否有标准方法来交换二元谓词的参数?

Is there a standard way to swap arguments for a binary predicate?

我想使用 std::lower_bound(找到大于或等于)在容器中找到小于或等于的最后一个值,并为我的类型设置一个比较谓词,f.e.

bool valComp(MyType lhs MyType rhs){ return lhs.value_ < rhs.value_; }

我能以某种方式简洁地调用 reverse std::lower_bound 和谓词的反向参数吗

std::lower_bound(myVec.rbegin(), myVec.rend(), myVal, std::i_dont_know(valComp));

还是我最好复制谓词/在 lambda 中手动交换它们/滚动我自己的模板?

对于通用情况,标准库中没有适配器,但编写起来很容易;

template <typename Comp>
struct reversed_compare : Comp
{
    template <typename T1, typename T2>
    auto operator()(T1&& lhs, T2&& rhs) const
    {
        return Comp::operator()(std::forward<T2>(rhs), std::forward<T1>(lhs));
    }
};

对于反转<的特定情况,您可以使用std::greater(即函数对象>

std::lower_bound(myVec.rbegin(), myVec.rend(), myVal, std::greater{});

在 C++14 中你需要 std::greater<>{},在 C++11 中你需要 std::greater<decltype(myVec)::value_type>{} 或类似的。

lambda 很短:

// std::lower_bound(myVec.rbegin(), myVec.rend(), myVal,
    [&valComp](const auto& l, const auto& r) { return valComp(r, l); }
// );

标准的内置解决方案是 std::bind

// std::lower_bound(myVec.rbegin(), myVec.rend(), myVal,
    std::bind(valComp, std::placeholders::_2, std::placeholders::_1)
// );

但是 lambda 普遍更具可读性。您可以制作一个辅助函数,以简化使用时的操作:

template<typename F>
auto swap_two_args(F&& f) {
    return [f=std::forward<F>(f)](auto&& l, auto&& r) {
        return f(std::forward<decltype(r)>(r), std::forward<decltype(l)>(l));
    };
}


// std::lower_bound(myVec.rbegin(), myVec.rend(), myVal,
    swap_two_args(valComp)
// );