Can anyone explain the output I am getting from this simple program using std::map
. Note that I insert p
into the map, but not q
yet i
In order to use a data type in an std::map
, it must have a particular ordering called a strict weak ordering (https://en.wikipedia.org/wiki/Weak_ordering). This means that the inequality operator (<
) obeys a very specific set of rules. The operator you specified however is not a weak ordering. In particular, given two screenPoint
s, a
and b
constructed from (1,2) and (2,1) respectively, you will see that it is false both that a < b
and that b < a
. In a strict weak ordering, this would be required to imply that a == b
, which is not true!
Because your inequality operator does not meet the requirement of a strict weak ordering, map
ends up doing unexpected things. I recommend reading up more details on what this ordering is, and reading/thinking about why map requires it. In the short term, you can redefine your operator as follows:
bool operator<(const screenPoint& left, const screenPoint& right){
if (left.x != right.x) return left.x < right.x;
else return (left.y < right.y);
}
The problem is with the way you defined the comparison functor, in this case. The two elements, p
, and q
, have the same x
and y
, just inverted.
Your logic checks that the x
of one is less than that of the other, as well as the y
s. This can never evaluate to true
, for these inputs.
Try this snippet:
int main()
{
auto p = screenPoint(1,2);
auto q = screenPoint(2,1);
std::cout << std::boolalpha << (p < q) << " " << (q < p) << std::endl;
}
It will print out
false false
So p
is not less than q
, and q
is not less than p
. As far as the map is concerned, that makes them equivalent.