chamibuddhika
chamibuddhika

Reputation: 1439

STL map custom comparator

I am trying to use a user defined type as a map key with a custom comparator as follows.

#include <map>
#include <iostream>

class RangeKey {
  public:
    int start;
    int end;

    RangeKey(int start, int end) : start(start), end(end) {

    }

    bool withinRange(int value, bool inclusive) const {
      if (inclusive) {
        return (value >= start && value <= end);
    } else {
      return (value > start && value < end);
    }
  }

  bool overlapsWith(const RangeKey& r) const {
    if (r.withinRange(start, true) ||
        r.withinRange(end, true) ||
        (start < r.start && end > r.end)) {
      return true;
    }
    return false;
  }

};

class RangeKeyComparator {
  public:
    bool operator()(const RangeKey& a, const RangeKey& b) const {
      if (a.overlapsWith(b)) {
        return true;
      } else {
        return a.start < b.start;
      }
    }
};

int main() {
  std::map<RangeKey, int, RangeKeyComparator> m;
  m.insert(std::pair<RangeKey, int>(RangeKey(1, 2), 1));
  auto it = m.find(RangeKey(1, 2));

  std::cout << it->first.start << "\n";
  std::cout << it->first.end << "\n";
  std::cout << it->second << "\n";

  return 0;
}

The idea is to consider two RangeKey instances as equal if their ranges overlap. However when I try to retrieve a value after the insertion it gives me some garbage values as the main function output. What am I doing wrong here?

Upvotes: 0

Views: 1803

Answers (1)

John Zwinck
John Zwinck

Reputation: 249133

The comparator for a map needs to be a "strict weak ordering," i.e. it cannot be that Comp(A,B) returns true and also Comp(B,A) returns true. Your comparator is a violation of this.

Upvotes: 6

Related Questions