【问题标题】:Does ranges::lower_bound have different requirements for the comparison than std::lower_bound?range::lower_bound 对比较的要求是否与 std::lower_bound 不同?
【发布时间】:2021-06-29 08:30:00
【问题描述】:

似乎在 C++20 中使用与 std::lower_bound() 正常工作的相同比较函子不适用于 std::ranges::lower_bound()。以下代码不能与 Visual Studio 16.10.2(和 /std::c++latest)或 gcc 11.1 一起编译。我可以通过使用投影而不是比较函子来解决这个问题,但这会增加迁移的工作量。

std::ranges::lower_bound() 中参数“comp”的要求是否与 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:“运算符 __surrogate_func”:未找到匹配的重载函数
错误 C7602: 'std::ranges::_Lower_bound_fn::operator ()': 不满足相关约束

【问题讨论】:

    标签: c++ c++20


    【解决方案1】:

    是的。

    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 只需比较,只需(A&amp;, const double&amp;) 表单即可。

    【讨论】:

    • 如果我们不使用自定义比较器,而是为A 定义&lt;=&gt; 宇宙飞船运算符并使用语法auto z = std::ranges::lower_bound(v, A(2.0));,它会工作吗?我似乎无法让它在我的项目中工作。我可能遗漏了什么。
    猜你喜欢
    • 2017-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    • 2011-11-21
    • 2012-02-05
    • 2022-01-26
    • 1970-01-01
    相关资源
    最近更新 更多