无法将数据插入std :: set。丢弃为重复

时间:2016-06-05 11:29:15

标签: c++ set std

struct Room
{
    int room;
    int x,y;
    int dist;
    Room(){}Room(int _room,int xx,int yy,int _dist)
    {
        x = xx;
        y = yy;
        room = _room;
        dist = _dist;
    }

    bool operator < (const Room& tempRoom)const
    {
        return dist < tempRoom.dist;
    }
};

int main()
{
    set<Room>que;
    que.insert(Room(0,0,0,1));
    que.insert(Room(0,0,0,1));
    que.insert(Room(1,2,0,1));
    que.insert(Room(0,2,0,1));
    for(auto itr = que.begin(); itr != que.end();itr++)
        cout<<itr->room<<","<<itr->x<<","<<itr->y<<","<<itr->dist<<endl;

    return 0;
}

显示输出0,0,0,1。但它应该是

0,0,0,1

1,2,0,1

0,2,0,1

我知道它与运算符重载有关。我试过重载==运算符。但在搜索之后我发现只使用了套装&lt;运营商进行任何比较。如何修改&lt;运算符重载函数实现上述输出?感谢。

3 个答案:

答案 0 :(得分:3)

您只能按dist进行比较,因此具有相同dist的2个对象将相等。通过使对象不同的所有事情来修复比较。

这样的事情:

bool operator < (const Room& lhs, const Room& rhs)
{
    return
        std::tie(lhs.dist, lhs.room, lhs.x, lhs.y) <
        std::tie(rhs.dist, rhs.room, rhs.x, rhs.y);
}

另外,我使用非成员函数作为比较运算符。

答案 1 :(得分:2)

为了在集合中有用,您的operator <需要考虑所有相关字段,而不仅仅是dist

bool operator < (const Room& other)const {
    return
        dist < other.dist
    || (dist == other.dist && room < other.room)
    || (dist == other.dist && room == other.room && x < other.x)
    || (dist == other.dist && room == other.room && x == other.x && y < other.y);
}

答案 2 :(得分:2)

您当前的less-than运算符仅考虑字段dist。当ab都不会产生a < b时,有序关联容器会考虑两个对象b < atrue 等效。当已经存在与要插入的对象等效的元素时,将忽略插入(并且return ed对将指向具有first成员的新元素并使用false in second成员表示没有插入任何对象。

如果你想在所有成员相等的情况下只考虑你的对象,你可以使用一个只考虑所有成员的小于运算符。最简单的方法是使用临时std::tuple来使用less-than运算符:

bool Room::operator< (Room const& tempRoom) const {
    return std::tie(this->x, this->y, this->room, this->dist)
         < std::tie(tempRoom.x, tempRoom.y, tempRoom.room, tempRoom.dist);
}

此比较运算符使用元素的小于运算符来确定元素聚合的顺序。您也可以使用任何其他适合的比较,只要它定义严格的弱顺序。