Compare function for std::lower_bound

时间:2018-03-23 00:30:47

标签: c++ stl comparison binary-search

I have a class PersonsDB with a member variable __emails which is supposed to be a sorted vector of pointers to objects of class Person (sorted by Person emails). My plan was to use lower_bound with custom comparison function to get the iterator of where to insert my next pointer. Member function email() returns just a string.

bool PersonsDB::compare_email(Person * person_1, Person * person_2) const {
    return ((*person_1).email() < (*person_2).email());
}

vector<Person *>::iterator PersonsDB::email_exists(const string & email) {

    Person * dummy_person = new Person("", "", email, 0);

    auto i = lower_bound(__emails.begin(), __emails.end(), dummy_person, compare_email);

    if (i != __emails.end() && !((*dummy_person).email() < (*i)->email()))
        return i; // found
    else
        return __emails.end(); // not found

}

I tried to follow this answer that suggests to create a dummy object. My code however wouldn't compile with the following error:

   main.cpp:121:87: error: invalid use of non-static member function ‘bool PersonsDB::compare_email(Person*, Person*) const’
         auto i = lower_bound(__emails.begin(), __emails.end(), dummy_person, compare_email);
                                                                                           ^

I would appreciate any help, thanks!

1 个答案:

答案 0 :(得分:2)

Even though you're not specifically asking about this, but... there's no need to create a dummy_person (let alone on the heap!): lower_bound can use a heterogeneous comparison functor:

std::vector<Person *>::iterator
PersonsDB::email_exists(const std::string & email) {
    auto it = std::lower_bound(
        __emails.begin(), __emails.end(), email,
        [](Person * p, const std::string & s) { return p->email() < s; });

    return (it != __emails.end() && it->email() == email)
           ? it
           : __emails.end();
}

The comparison functor is most easily expressed as a lambda, no need for a named function.