2010-06-22 3 views
0

У меня есть простые структуры, которые я использую в качестве ключа в станде :: Картастанда :: Карта :: найти()

struct PpointKey{ 
     unsigned int xp,yp; //pixel coordinates 

     unsigned int side; 

     PpointKey(unsigned xp,unsigned yp,unsigned side=5):xp(xp),yp(yp),side(side) 
     {} 


     bool operator==(const PpointKey& other) const{ 
       const unsigned int x = other.xp; 
       const unsigned int y = other.yp; 

       return ((x>=xp && x<=xp+side) && (y>=yp && y<=yp+side)); 
     } 

     bool operator<(const PpointKey& other) const{ 

       const unsigned int x = other.xp; 
       const unsigned int y = other.yp; 

       const unsigned other_distance_2 = x*x + y*y; 

       const unsigned this_distance_2 = this->xp*this->xp + this->yp * this->yp; 

       return this_distance_2 < other_distance_2; 
     } 
}; 

То, что я хотел бы добиться того, чтобы использовать находку () для доступа к карте с ключом, который имеет свои атрибуты xp, yp в пределах расстояния side. Другими словами, если у меня есть (х, у) кортеж, я хотел бы найти внутри карты первый PpointKey, который удовлетворяет условию внутри оператора == функции

return ((x>=xp && x<=xp+side) && (y>=yp && y<=yp+side)); 

Возможно ли это с помощью найти? Я получаю map.end(), поэтому я хотел бы проверить, что функция find() использует оператор ==. Может быть, алгоритм поиска будет лучше?

Заранее спасибо.

+0

Имейте в виду, что 'std :: map' использует только' operator <'. Два ключа считаются равными, если ни один из них не является меньшим, чем другой. –

ответ

1

Функция findmap не использует operator==.

Однако вы можете использовать std::find, минуя begin() и end() итератор map. Он будет просто перебирать последовательность по одному и давать первый объект, который соответствует (сложность линейна).

Проблема, с которой вы столкнулись, связана с тем, что вы злоупотребляли перегрузкой оператора. Проблема здесь состоит в том, что общее определение operator== является:

T operator==(T lhs, T rhs) 
{ 
    return !(lhs < rhs) && !(rhs < lhs); 
} 

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

Было бы лучше, если бы вы использовали традиционные функции с выразительными именами, а не с перегрузкой оператора, это было бы менее вводить в заблуждение. Обратите внимание, что map и std::find позволяют передавать подходящие предикатные объекты, вам не нужно перегружать операторов для их использования.

+0

Но 'std :: find()' будет оператором на 'std :: pair ::', а не на 'Key'. Итак, 'std :: find_if()' с соответствующим предикатом следует использовать, правильно? – sbi

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