2009-05-15 2 views
13

Я хочу найти первый элемент в отсортированном векторе, который имеет поле меньше некоторого значения x.
Мне нужно предоставить функцию сравнения, которая сравнивает «x» с внутренним значением в MyClass, но я не могу выработать объявление функции.
Не могу я просто перегружать '<', но как это сделать, когда аргументы "& MyClass 'и' float '?сравнить функцию для upper_bound/lower_bound

float x; 
std::vector<MyClass>::iterator last = std::upper_bound(myClass.begin(),myClass.end(),x); 

ответ

15

Какую функцию вы перешли к алгоритму сортировки? Вы должны иметь возможность использовать один и тот же для upper_bound и lower_bound.

Самый простой способ сделать работу сравнения - создать фиктивный объект с полем ключа, заданным для вашего значения поиска. Тогда сравнение всегда будет между подобными объектами.

Редактировать: Если по какой-либо причине вы не можете получить фиктивный объект с соответствующим сравнительным значением, тогда вы можете создать функтор сравнения. Функтор может обеспечить три перегрузки для оператора():

struct MyClassLessThan 
{ 
    bool operator() (const MyClass & left, const MyClass & right) 
    { 
     return left.key < right.key; 
    } 
    bool operator() (const MyClass & left, float right) 
    { 
     return left.key < right; 
    } 
    bool operator() (float left, const MyClass & right) 
    { 
     return left < right.key; 
    } 
}; 

Как вы можете видеть, что это долгий путь, чтобы идти о нем.

+0

В этом была проблема, функция sort принимает два const refs для объектов MyClass. Функция поиска должна принимать MyClass и float. Та же проблема для использования bind2nd() –

+0

operator(), чтобы сравнить вещи - теперь почему я не подумал об этом !!! Чем больше я использую STL, тем больше я люблю питон. спасибо –

+0

не должен быть const MyClass & left, const MyClass & right? – chmike

0

Я думаю, что вам нужно это std::bind2nd(std::less<MyClass>(), x). Но, конечно, для MyClass должен быть определен оператор <.

Редактировать: о, и я думаю, вам понадобится конструктор для MyClass, который принимает только float, чтобы он мог быть неявно преобразован. Однако может быть лучший способ сделать это.

6

Вы можете дополнительно улучшить решение Марка путем создания статического экземпляра MyClassLessThan в MyClass

class CMyClass 
{ 
    static struct _CompareFloatField 
    { 
     bool operator() (const MyClass & left, float right) //... 
     // ... 
    } CompareFloatField; 
}; 

Таким образом, вы можете позвонить lower_bound следующим образом:

std::lower_bound(coll.begin(), coll.end(), target, CMyClass::CompareFloatField); 

Это делает его немного более читаемый

+1

Мне по-прежнему нужен фиктивный объект и оператор() для каждого участника, но ваш читатель более ясен в чтении намерения - спасибо –

Смежные вопросы