std::equal_range не работает с Strucutre с оператором <определено

Я пытаюсь использовать std::equal_range со структурой ниже у меня есть ошибка компиляции, говорящая, что error: no match for ‘operator<’ ,

 struct MyFoo {
    int     v_;
    string  n_;
    bool operator<(int v) const
    { return v_ < v;}
 };

 vector<MyFoo> data; 
 // data is sorted by int v_
 typedef vector<MyFoo>::iterator Ptr;
 std::pair< Ptr, Ptr > pr = std::equal_range(data.begin(), data.end(), 10);

Я посмотрел в шаблоне ввода-вывода и что терпит неудачу, это следующее где *it защищает итератор, указывающий на объект MyFoo и val_ это 10.

 if(*it < val_) {
  ...
 }

Почему это не работает? Я думал, вероятно, потому что он пытается назвать глобальный operator< это не определено, но так как я определил это как член класса, это не должно быть проблемой, не так ли?

3 ответа

Решение

Предоставьте операторы сравнения, не являющиеся членами:

 bool operator<(int v, const MyFoo& foo)
 { 
   return foo.v_ < v;
 }

 bool operator<(const MyFoo& foo, int v)
 {
   return v < foo;
 }

Кроме того, вы можете предоставить оператор преобразования int:

operator int() cont {return v_;}

Что, вероятно, нежелательно, так как компилятор сможет выполнять тихие преобразования в других местах вашего кода.

Как другая альтернатива: предоставить

bool operator<(const MyFoo& rhs) const { return v_ < rhs.v_; }

И использовать std::equal_range на фиктивном объекте с правильным v_ как:

std::pair<Ptr, Ptr> pr = std::equal_range(data.begin(), data.end(), MyFoo{10, ""});

У вас могут быть проблемы, потому что реализация std::equal_range использует std::less. Это попытается преобразовать ваш MyFoo в int для сравнения, а не просто с помощью перегрузки operator<(). Попробуйте добавить это в свой класс MyFoo...

operator int() const
{
    return v_;
}
Другие вопросы по тегам