2016-08-19 4 views
-3

Wenn ich versuche, Elemente meiner Karte zu löschen, scheint es ein anderes Element zu sein, das stattdessen gelöscht wird. Ich dachte, es war eine schlechte Überschreibung von Operator <, aber ich sehe das Problem nicht.Std :: Karte löschen falsches Element

inline bool operator<(const Etat &et){ 
    if (et.x < this->x){ 
     return false; 
    } 
    else if (et.x > this->x){ 
     return true; 
    } 
    if (et.y < this->y){ 
     return false; 
    } 
    else if (et.y > this->y){ 
     return true; 
    } 
    if (et.ry < this->ry){ 
     return false; 
    } 
    else if (et.ry > this->ry){ 
     return true; 
    } 
}; 

Etat Konstruktor:

Etat(x, y, ry, useless, useless); 

und die Karte:

std::map< Etat, double > map; 
//The 2 last parameters of Etat are useless 
map.insert(std::pair< Etat, double >(Etat(2, 2, 2, 0, 0), 0.0)); 
//map.size() = 1 
Etat e (0, 5 ,3, 0, 0); 
map.erase(e); 
//map.size() = 0 
//Etat(2, 2, 2) is gone 

Ich habe nicht das Problem für alle Instanz von Etat in der Karte, nur dieser Fall auf und einige Andere.

Testen Sie es zu Hause:

std::map< Etat, double > map; 
map.insert(std::pair< Etat, double >(Etat(2, 2, 2, 0, 0), 0.0)); 
Etat e (0, 5 ,3, 0, 0); 
map.erase(e); 
+3

Bekommen Sie wirklich nicht a [Warnung] (http://coliru.stacked-crooked.com/a/0454caf5304f2b86) für diesen Code? – chris

+4

Wenn die beiden Elemente gleich sind, stimmt keiner der 'if'-Blöcke überein. – Barmar

+0

ya Ich weiß, weil es unmöglich für sie ist, gleich zu sein – Milow

Antwort

2

Um Ihre Klasse als Schlüssel in der Karte zu verwenden, definieren Sie müssen, wenn Sie Ihre Elemente sind:

#ifndef Etat_H 
#define Etat_H 

#include<iostream> 

class Etat 
{ 
public: 
Etat(const int x, const int y, const int ry, const double vx, const double vy) 
{ 
    this->x = x; 
    this->y = y; 
    this->ry = ry; 
    this->vx = vx; 
    this->vy = vy; 
}; 

Etat(){}; 
inline bool operator==(const Etat& et){ 
    if (et.x == this->x && et.y == this->y && et.ry == this->ry && et.vx == this->vx && et.vy == this->vy){ 
     return true; 
    } 
    return false; 
}; 
inline bool operator!=(const Etat& et){ 
    if (*this == et){ 
     return false; 
    } 
    return true; 
}; 
inline bool operator<(const Etat &et){ 
    if (et.x < this->x){ 
     return false; 
    } 
    else if (et.x > this->x){ 
     return true; 
    } 
    if (et.y < this->y){ 
     return false; 
    } 
    else if (et.y > this->y){ 
     return true; 
    } 
    if (et.ry < this->ry){ 
     return false; 
    } 
    else if (et.ry > this->ry){ 
     return true; 
    } 
}; 

inline bool operator>(const Etat& et){ 
    if (*this < et){ 
     return false; 
    } 
    return true; 
}; 

inline const int getX() const { 
    return this->x; 
}; 

inline const int getY() const { 
    return this->y; 
}; 

inline const int getRY() const { 
    return this->ry; 
}; 

private: 
    int x, y; 
    int ry; 
    double vx, vy; 
}; 

#endif // !Etat_H 

Das kleine Stück Code, das Problem reproduzieren gleich. So Komparator Klasse definieren:

struct EtatCompare { 
    bool operator() (const Etat& e1, const Etat& e2) const { 
     return e1.x != e2.x || e1.y != e2.y || e1.ry != e2.ry || e1.vx != e2.vx || e1.vy != e2.vy; //TODO: fill all the needed conditions here 
    } 
}; 

und es verwenden, Karte erstellen:

std::map< Etat, double, EtatCompare > map; 
+0

nicht sicher zu verstehen, x = 2, x '= 0, e1 falsch, e2 wahr. Es ist nicht falsch in beiden Fällen – Milow

+1

@Anton: schau es dir nochmal genauer an. Wenn die angegebenen Werte gegeben sind, gibt '(e1

+0

@RemyLebeau Ja, es ist Abend hier :) so scheint das Problem nicht in Operator

1

Ihr fehlt ein

else { 
    throw "no matching if"; // alternatively return either true or false. 
} 

Ihr Compiler sollte eine Warnung geben, dass es einen Fall gibt, wo es keine Rückkehr.

+0

Das stimmt. Ich füge das meinem Code hinzu, aber ich gehe nie zum Wurf – Milow

2

Nicht alle Pfade Ihres operator< geben einen Wert zurück. Insbesondere wenn et == *this.

Wenn Sie C++ 11 oder höher verwenden, verwenden std::tie() statt:

inline bool operator<(const Etat &rhs) const 
{ 
    return std::tie(x, y, ry) < std::tie(rhs.x, rhs.y, rhs.ry); 
} 

Sie können für Ihre operator== und operator> Implementierungen dasselbe tun:

bool operator==(const Etat &rhs) const 
{ 
    return std::tie(x, y, ry) == std::tie(rhs.x, rhs.y, rhs.ry); 
} 

bool operator>(const Etat &rhs) const 
{ 
    return std::tie(x, y, ry) > std::tie(rhs.x, rhs.y, rhs.ry); 
}