Reputation: 345
typedef struct Edge
{
int v1, v2, w;
bool operator <(const Edge &rhs) const{
bool b = v1 < rhs.v1 || v2 < rhs.v2;
return (b);
}
} edge;
template <class T>
struct my_less
{
bool operator()(const T& _Left, const T& _Right) const
{
return (_Left < _Right);
}
};
int main(int argc, char *argv[])
{
set <edge, my_less<edge> > F;
edge e3 = { 3, 3, 3};
edge e4 = { 3, 7, 3};
edge e5 = { 2, 7, 3};
F.insert(e3);
printf("e3 ? %d\n", F.find(e3)!=F.end()); // O
printf("e4 ? %d\n", F.find(e4)!=F.end()); // O
printf("e5 ? %d\n", F.find(e5)!=F.end()); // X
//printf("%d\n", e3<e4);
return 0;
}
If run this code, I got an error at "F.find(e5)!=F.end()" with following message. "Debug Assertion Failed!. Expression: invalid operator < " The condition of two edges of '(x,y), (p,q)' equality is !(x < p || y < q) && !(p < x || q < y) It can be '(x>=p && y>=q) && (p>=x && q>=y)' I really don't know why assertion raised. Is there something wrong?
Upvotes: 3
Views: 1729
Reputation: 38218
Your comparison doesn't enforce a strict ordering. For example:
Edge e1;
Edge e2;
e1.v1 = 5;
e1.v2 = 4;
e2.v1 = 4;
e2.v2 = 5;
// e1 < e2 is true
// e2 < e1 is true
// So which one should we really trust? Neither, let's abort the program!
You need to make your <
operator actually work like <
should. If e1 < e2
is true, then e2 < e1
needs to be false.
I think this might be what you want, but beware that I haven't tested it:
return v1 < rhs.v1 || (v1 == rhs.v1 && v2 < rhs.v2);
This should, in theory, sort by v1
, and use v2
to break ties.
Upvotes: 7