Функция сравнения для 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, чтобы он мог быть неявно преобразован. Однако может быть лучший способ сделать это.