2016-08-19 2 views
-3

Когда я пытаюсь стереть элементы моей карты, это похоже на другой элемент, который стирается вместо этого. Я думал, что это плохой подход оператора <, но я не вижу проблемы.std :: map стереть неправильный элемент

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 конструктор:

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

и карта:

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 

У меня нет проблемы для всего экземпляра Etat в карте, только в этом случае, и некоторые другие.

испытания его дома:

#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 

Маленький кусочек кода может воспроизвести проблему:

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

ли вы на самом деле не получить [предупреждение] (http://coliru.stacked-crooked.com/a/0454caf5304f2b86) для этого кода? – chris

+4

Если оба элемента равны, ни один из блоков 'if' не соответствует. – Barmar

+0

ya Я знаю, потому что невозможно быть равным – Milow

ответ

2

Чтобы использовать класс в качестве ключа в карте, вы должны определить, когда ваши элементы равны. Таким образом, определить компаратор класс:

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 
    } 
}; 

И использовать его не создавая карту:

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

не уверен в обслуживании, x = 2, x '= 0, e1 false, e2 true. Это не ложь в обоих случаях – Milow

+1

@ Антон: посмотрите на него еще раз более тщательно. Учитывая приведенные значения, '(e1

+0

@RemyLebeau да, здесь вечер :), поэтому проблема, похоже, не в самом операторе <, проблема в том, что этот оператор вообще не используется внутри карты. Вместо этого карта использует компаратор. Так что только последняя часть моего ответа верна, отредактирует ответ. –

1

Ваш отсутствует знак

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

Ваш компилятор должен дать предупреждение, что есть случай, когда нет вернуть.

+0

Правильно. Я добавляю это в свой код, но я никогда не хожу в бросок – Milow

2

Не все пути вашего operator< возвращают значение. В частности, когда et == *this.

Если вы используете C++ 11 или более поздней версии, используйте вместо std::tie():

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

Вы можете сделать то же самое для operator== и operator> реализаций:

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); 
} 
Смежные вопросы