Search code examples
c++c++11stdstdset

set::find finds an element that does not exist


I have the following Edgeclass:

class Edge {
public:
int src, dest;

bool operator== (const Edge &edge) const {
    return ((src == edge.src) && (dest == edge.dest)) || ((src == edge.dest) && (dest == edge.src));
}

bool operator<(const Edge& edge) const {
    return !(((src == edge.src) && (dest == edge.dest)) || ((src == edge.dest) && (dest == edge.src)));
}

Edge(int src, int dest) {
    this->src = src;
    this->dest = dest;
}
};

The point of overriding the < operator is when I try to find an edge in a set Edge(0, 1) should be equal to Edge(1, 0). However, the following test code fails to do so and std::find returns an edge that doesn't even exist:

Edge edge(0, 3);
set<Edge> test;
test.insert(Edge(3, 1));
test.insert(Edge(3, 0));
auto a = test.find(edge);
cout << a->src << " " << a->dest << endl;

This will strangely print out 2 0. I can't figure out why and I'm new to C++ any help is appreciated.


Solution

  • You currently don't have a valid Compare for std::set, so your program has undefined behaviour.

    Here is one that is compatible with your ==

    bool operator<(const Edge& edge) const {
        return std::minmax(src, dest) < std::minmax(edge.src, edge.dest);
    }
    

    This can also be used to simplify your ==

    bool operator==(const Edge& edge) const {
        return std::minmax(src, dest) == std::minmax(edge.src, edge.dest);
    }