What is this use of std::map doing?

后端 未结 2 616
孤街浪徒
孤街浪徒 2021-01-19 02:09

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

相关标签:
2条回答
  • 2021-01-19 02:39

    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 screenPoints, 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);
    }
    
    0 讨论(0)
  • 2021-01-19 02:43

    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 ys. 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.

    0 讨论(0)
提交回复
热议问题