'C++ std::set cannot find element after insertion

I am doing a traversing of points on an image. An std::set<Point> visited_ is maintained to keep track of all Points visited. Point is a simple struct with two unsigned coordinates, an operator<, and an operator==:

struct Point {
  unsigned x;
  unsigned y;

  // Constructors ...

  bool operator<(const Point &other) const {
    return (x < other.x || y < other.y);
  }

  bool operator==(const Point &other) const {
    return (x == other.x && y == other.y);
  }
};

However, after I insert()'d a Point into the set visited_, using std::set::find() does not find the inserted Point in some cases. Doing a range-based for loop on the set shows that the Point is successfully inserted. Code snippet I used for testing:

  // ret is the point to be added
  visited_.insert(ret);

  // range-based for loop printing every node visited
  std::cout << "Currently visited: ";
  for (auto& point : visited_) {
    std::cout << point << " ";
  }
  std::cout << std::endl;

  // check if std::set::find() finds the point
  std::cout << "Checking " << ret << " in visited_: " << (visited_.find(ret) != visited_.end()) << std::endl;

The result is very surprising:

Currently visited: (2, 2)      <-- (2, 2) inserted
Checking (2, 2) in visited_: 1 <-- (2, 2) can be detected by find()
Currently visited: (2, 1) (2, 2) 
Checking (2, 1) in visited_: 1
Currently visited: (1, 1) (2, 1) (2, 2) 
Checking (1, 1) in visited_: 1
Currently visited: (1, 1) (1, 2) (2, 1) (2, 2) <-- (1, 2) is inserted!
Checking (1, 2) in visited_: 0                 <-- ??? 
Currently visited: (1, 1) (1, 2) (2, 1) (3, 1) (2, 2) <-- same thing happens to (3, 1)
Checking (3, 1) in visited_: 0
Currently visited: (1, 1) (1, 2) (2, 1) (3, 1) (2, 2) (3, 2) 
Checking (3, 2) in visited_: 1

What could possibly cause this problem?

Edit: As @chris kindly mentioned in the comments, the operator< has weird conditions (example: (0, 1) and (1, 0) are smaller than each other). However, a self-defined compare class also yields the same results:

  class PointCompare {
    bool operator() (const Point& lhs, const Point& rhs) {
      if (lhs.x != rhs.x) return lhs.x < rhs.x;
      return lhs.y < rhs.y;
    }
  };

  std::set<Point, PointCompare> visited_;

P.S. I am not using contains() since the C++ standard for the project is C++14. contains() is only available in C++20.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source