Debug Assertion Failed...invalid operator >



  • Hi,
    erstmal bisl code der hoffentlich ausreicht...

    class Position
    {
    public:
    	int x,y,z;
    
    	Position(){}
    	Position(int x, int y, int z){
    		this->x = x;
    		this->y = y;
    		this->z = z;
    
    	bool operator < (const Position &pos) const{
    		if(pos.x > x || pos.y > y || pos.z > z)
    			return true;
    		return false;
    	}
    
    };
    
    class World{
    private:
    	map<Position ,WorldPoint> point;
    ...
    };
    
    World::World(){
    	this->cell = new Cell(this);
    	srand ( time(NULL) );
    
    	for(int i = 0; i < 10; ++i){ // diese schleife mein ich
    		int x = rand() % 30;
    		int y = rand() % 30;
    		int z = rand() % 30;
    		Position pos(x,y,z);
    
    		if(point.count(pos) > 0)
    			continue;
    
    		point[pos].cell = (this->cell);
    		point[pos].options = 0;
    
    	}
    }
    

    Beim Zweiten durchlauf der Schleife bekomm ich folgenen Debug Fehler:

    Debug Assertion Failed!
    ...
    Expression: invalid operator<
    ...

    weiß einer woran das liegen könnte? Ist dem Map-Type der operator < nicht eindeutig genug? Oder sind es zu wenig informationen um den Grund herrauszufinden?

    Mfg Landau 🙂



  • Er erfüllt die Bedingungen für Strict Weak Ordering nicht, nach dem alle Elemente eindeutig geordnet werden können.

    Position(1,1,3) < Position(1,2,1) == true
    Position(1,2,1) < Position(1,1,3) == true
    

    Nimm ausserdem keinen Vergleichsoperator. Überlade Operatoren nur, wenn ihre Semantik intuitiv ist. Das ist bei 3D-Vektoren definitiv nicht der Fall ("wann ist eine Position grösser als eine andere" wird von 10 Leuten auf 7 unterschiedliche Arten beantwortet). Schreib dir also einen globalen Funktor, und überlege dir ein eindeutiges Sortierkriterium.

    struct ComparePosition
    {
        bool operator() (const Position& Left, const Position& Right) const;
    };
    


  • hier mal ein funktionierender vergleichsoperator:

    struct vector_comparer
    {
      bool operator() (const Position& lhs, const Position& rhs) const
      {
        if(lhs.x != rhs.x)
          return lhs.x < rhs.x;
    
        if(lhs.y != rhs.y)
          return lhs.y < rhs.y;
    
        return lhs.z < rhs.z;
      }
    };
    

    bb



  • Deinen def-ctor kannste in die Tonne treten, weil er "leer" ist und nichtmal die 3D-Koordinaten initialisiert. Und dann solltest du nicht den Weg über den this-Zeiger nehmen. Klopp nen bisschen Design rein und nenn die Koord. m_x, m_y und m_z. Dann kannste die auch direkt in der Initialisierungsliste des ctors initialisieren.

    Und naja, wie schon gesagt wurde, so wie du den <-Operator überladen hast, bringt er dir überhaupt nichts im 3D-Raum. Ansonsten könnteste zur Verschönerung noch von Boost::Operators erben...



  • Kóyaánasqatsi schrieb:

    Deinen def-ctor kannste in die Tonne treten, weil er "leer" ist und nichtmal die 3D-Koordinaten initialisiert.

    Die Aussage willst du vielleicht nochmal überdenken.



  • Der Standardkonstruktor sollte die Koordinaten schon initialisieren, z.B. als Nullvektor. Vielleicht ist es nicht die schlechteste Idee, gar nicht erst einen Standardkonstruktor bereitzustellen. Sowas wie m_x würde ich dennoch nicht verwenden, weil es den Code hässlich macht:

    pos.m_x = 4;
    

    Ist auch gar kein Problem, in der Initialisierungliste Member zu initialisieren, die gleich wie Parameter heissen.

    Position(int x, int y, int z) : x(x), y(y), z(z)
    {
    }
    

Anmelden zum Antworten