Why is this std :: map key not found?

I asked a similar question before, and now I have a problem with this. Below is "not found" and the number of printed items is 2.

String positions.emplace(r,q); clearly inserts the element, and the card size is correct, so why is r not found? p found (not registered in this example).

 #include <map> #include <iostream> struct screenPoint { float x = 0, y = 0; screenPoint(float x_, float y_): x{x_}, y{y_}{} }; bool operator<(const screenPoint& left, const screenPoint& right){ return left.x<right.x||left.y<right.y; } std::map<screenPoint, screenPoint> positions; int main(int argc, const char * argv[]) { auto p = screenPoint(593,271.5); auto q = screenPoint(595.5,269.5); auto r = screenPoint(599,267); positions.emplace(p,q); positions.emplace(r,q); auto f = positions.find(r); if (f == positions.end()){ std::cout << "not found"; } else { std::cout << "found"; } std::cout << std::endl; std::cout << "number elements: " << positions.size() << "\n"; return 0; } 
+2
source share
2 answers

Your comparison operator

 bool operator<(const screenPoint& left, const screenPoint& right){ return left.x<right.x||left.y<right.y; } 

Wrong. You need to use an if statement, and if x equal to return, if left.y less than right.y otherwise return left.x < right.x . or use std::tie as

 bool operator<(const screenPoint& left, const screenPoint& right){ return std::tie(left.x, left.y) < std::tie(right.x, right.y); } 
+2
source

Your operator< not a strict weak order. You have, for example, p<q and q<p . This means Undefined Behavior for any map operations.

One way to provide a valid operator< that ignores NaN would be:

 bool operator<(const screenPoint& left, const screenPoint& right) { return left.x < right.x || ( left.x == right.x && left.y < right.y ); } 
+3
source

All Articles