Функция сравнения для upper_bound/lower_bound
Я хочу найти первый элемент в отсортированном векторе, у которого поле меньше некоторого значения x.
Мне нужно предоставить функцию сравнения, которая сравнивает "x" с внутренним значением в MyClass, но я не могу обработать объявление функции.
Не могу я просто перегрузить '<' но как это сделать, когда аргументы "& MyClass" и "float"?
float x;
std::vector< MyClass >::iterator last = std::upper_bound(myClass.begin(),myClass.end(),x);
Ответы
Ответ 1
Какую функцию вы перешли к алгоритму сортировки? Вы должны иметь возможность использовать один и тот же для 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;
}
};
Как вы можете видеть, это длинный путь для этого.
Ответ 2
Вы можете еще больше улучшить решение Mark, создав статический экземпляр 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);
Это делает его более читаемым
Ответ 3
Я думаю, что вам нужно std::bind2nd(std::less<MyClass>(), x)
. Но, конечно, оператор < должен быть определен для MyClass.
Изменить: о, и я думаю, вам понадобится конструктор для MyClass, который принимает только float, чтобы он мог быть неявно преобразован. Однако может быть лучший способ сделать это.