'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 |
|---|
