在成员变量上执行std :: upper_bound的任何方法

Any way to do a std::upper_bound on a member variable?

本文关键字:bound 任何 方法 upper 变量 执行 std 成员      更新时间:2023-10-16

我想使用 std::upper_bound在某些容器中找到对象的跨度,这些对象较小或等于提供的值。这使它成为一个简单的单线!

问题是我只对与班级的特定原始成员进行比较感兴趣。对容器进行排序是没有问题的,但是当我想使用std::upper_bound时,我需要提供一个对象来比较功能以使其工作。

对于MCVE,假设我有很多人,我想找到一个迭代器:

struct Person {
    int age;
    double height;
    Person(int age, double height) : age(age), height(height) { }
};
int main() {
    vector<Person> people = { 
        Person(5, 12.3), 
        Person(42, 9.6), 
        Person(38, 18.4), 
        Person(31, 8.5)
    };
    auto sorter = [](const Person& a, const Person& b) {
        return a.height < b.height;
    };
    std::sort(people.begin(), people.end(), sorter);
    // All I care about is comparing against this number
    // Instead... I have to create a whole new struct
    //double cutoff = 10.0;
    Person cutoff(123, 10.0);
    auto it = std::upper_bound(people.begin(), people.end(), cutoff, sorter);
    // Do stuff with 'it' here
}

我遇到的问题是,我需要像上面的代码中那样实例化整个对象以使用std::upper_bound。我不能有"与我提供的价值的比较"。这使它非常烦人,因为我要与的对象对我而言并不容易在不做大量工作的情况下弹出。

是否有可行的策略可以解决这一问题,这将导致我能找到的最干净,最紧凑的代码?例如,如果我能做到的话,那就太好了(对于MCVE):

auto cutoffCompare = [](const Person& p, const double height) { 
    return p.height < height;
};
// Doesn't exist (AFAIK?)
auto it = std::upper_bound(people.begin(), people.end(), cutoff, sorter, cutoffCompare);

由于它处于程序中的热点,我在这个程序中更关心性能,而不是正常情况,所以我不能做诸如将对象转换为原始类型之类的事情,然后在该新列表上进行upper_bound。我可以创建一个全新的对象并将其用作假人,但是然后我将添加烦人的代码来做一些非常简单的事情。我是否坚持实例化对象?还是我必须滚动自己的upper_bound?

不需要传递给std::upper_bound的值必须匹配迭代器的类型,如果您提供正确的比较功能,则可能是您想要的任何东西。您所需的样本非常接近,只需要翻转论点即可。这里的文档表示比较函数将极限值作为第一个参数。

auto cutoffCompare = [](double height, const Person& p) { 
    return p.height < height;
};
auto it = std::upper_bound(people.begin(), people.end(), 10.0, cutoffCompare);