1

In my code I have those lines:

if(mymap.count(plan) == 0) {
    std::vector<XYZ> v;
    v.reserve(10);
    mymap.emplace(plan, v);
    std::cout << "Plan " << plan.normal << " @ " << plan.O << " added";
}

//I inserted this code for debugging
std::map<Plan, std::vector<XYZ>>::const_iterator it = mymap.find(plan);
if(it == this->intersections.end())
    std::cout << "not found";

How is it possible that I can read in the console plan added and just after not found ?

My map is declared as such:

std::map<Plan, std::vector<XYZ>, PlanComp> mymap;

At some point I thougt it comes from the comparator, but it respects irreflexivity, antisymmetry, transitivity, transitivity of equivalence (which is enough according to this blog) :

struct PlanComp {
  bool operator()(const Plan& l, const Plan& n) const {
    return (l.O.x != n.O.x) || (l.O.y != n.O.y) || (l.O.z != n.O.z)
            || (l.normal.x != n.normal.x) || (l.normal.y != n.normal.y) || (l.normal.z != n.normal.z);
  }
};

struct XYZ {
    double x;
    double y;
    double z;
};

struct Plan {
    XYZ O;
    XYZ plan;
};
Deewy
  • 245
  • 1
  • 8

1 Answers1

2

Your comparator does not define a strict weak ordering (loosely speaking, "less than" semantics which define an order for your elements). Therefore your code exhibits undefined behaviour.

The simplest solution would be to use a lexicographical comparator - compare x first, then compare y only in the event of a tie, and so on. In C++11 that's even simpler; operator < for tuples already does this for you (and you can use std::tie to get the tuples). See the answers to Operator < and strict weak ordering for examples.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680