std :: map擦除错误的元素

时间:2016-08-19 22:53:55

标签: c++ stdmap

当我尝试擦除地图的元素时,它似乎是另一个被删除的元素。 我认为这是一个糟糕的操作符覆盖<但我没有看到问题。

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 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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);
}

答案 2 :(得分:1)

你错过了

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

您的编译器应该发出警告,指出没有返回的情况。