是否有标准方法来交换二元谓词的参数?
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)
// );
我想使用 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)
// );