ranges::lower_bound对比较的要求是否与std::lower.bound不同



在C++20中,使用与std::lower_bound((配合良好的同一比较函数似乎无法与std::ranges::lower_bound((配合使用。以下代码不使用Visual Studio 16.10.2(和/std::c++最新版本(或gcc 11.1进行编译。我可以通过使用投影而不是比较函子来解决这个问题,但这会增加迁移的工作量。

论点的要求是";comp";在std::ranges::lower_bound((中,与std::lower_bound((不同,如果是,如何?

#include <algorithm>
#include <vector>
struct A {
double m_value;
};
struct MyComparison {
bool operator()(const A& a, const double& b) {
return a.m_value < b;
}
};
void f() {
std::vector<A> v = {A{1.0}, A{2.0}, A{3.0}};
// comparison functor without ranges compiles as expected:
auto x = std::lower_bound(v.cbegin(), v.cend(), 2.0, MyComparison());
// projection with ranges compiles as expected:
auto y = std::ranges::lower_bound(v, 2.0, {}, &A::m_value);
// comparison functor with ranges fails to compile:
auto z = std::ranges::lower_bound(v, 2.0, MyComparison());
}

Visual Studio中的错误消息:
错误C2672:"operator __surrogate_func":找不到匹配的重载函数
错C7602:"std::ranges::_Lower_bound_fn::operator((":不满足关联的约束

是的。

std::ranges::lower_boundComp必须是

std::indirect_strict_weak_order<const double*, std::vector<A>::iterator>

它扩展到的许多变体

std::strict_weak_order<Comp&, const double&, A&>

扩展到

std::predicate<Comp&, const double&, const double&> &&
std::predicate<Comp&, const double&, A&> &&
std::predicate<Comp&, A&,            const double&> &&
std::predicate<Comp&, A&,            A&>

因此,您需要能够处理参数类型的每一个排列。

std::lower_boundComp只需要Compare,这只适用于(A&, const double&)形式。

一种方法是使用投影将A结构转换为比较值。
auto lb = std::ranges::lower_bound( v, 2.0,
[]( double m_value, double rng ) { return rng < m_value; }, //comparison predicate using doubles
[]( auto const& myA ) { return myA.m_value; } ); //projection that converts from a A to a double. This projection should return the type used in the predicate comparison

最新更新