【问题标题】:Any way to do a std::upper_bound on a member variable?有什么方法可以对成员变量执行 std::upper_bound 吗?
【发布时间】:2019-03-06 06:59:39
【问题描述】:

我想使用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 之类的操作。我可以创建一个全新的对象并将其用作虚拟对象,但随后我将添加大量烦人的代码来做一些非常简单的事情。我被困在实例化对象了吗?还是我必须滚动自己的上限?

【问题讨论】:

标签: c++ c++17


【解决方案1】:

没有要求传递给std::upper_bound 的值必须与迭代器的类型匹配,如果您提供正确的比较函数,它可以是您想要的任何东西。你与你想要的样本非常接近,只需要翻转参数。文档here 表示比较函数将限制值作为第一个参数。

auto cutoffCompare = [](double height, const Person& p) { 
    return p.height < height;
};

auto it = std::upper_bound(people.begin(), people.end(), 10.0, cutoffCompare);

【讨论】:

  • 请注意,std::lower_boundstd::upper_bound 比较器的参数类型是“颠倒的”。
猜你喜欢
  • 1970-01-01
  • 2011-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-02
  • 2016-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多