I have a struct called foo, and also a map called mp, but for some reason, when I insert {5, 0, 3} and query for {5, 3, 0}, the map says that it contains {5, 3, 0} when it actually doesn't:
#include <bits/stdc++.h>
using namespace std;
struct foo {
int v1, v2, v3;
friend bool operator<(const foo &a, const foo &b) {
return a.v1 < b.v1;
}
friend bool operator==(const foo &a, const foo &b) {
return (a.v1 == b.v1) && (a.v2 == b.v2) && (a.v3 == b.v3);
}
};
int main() {
map<foo, int> mp;
mp[{5, 0, 3}] = 1;
if(mp[{5, 3, 0}]) {
cout << "YES\n";
} else {
cout << "NO\n";
}
return 0;
}
Output:
YES
Does anyone know why my code is doing this? If so, what do I need to change?
Your comparison operator does not match your equality operator. A
std::mapdoes not use the equality operator; it uses "less than". If neithera < bnorb < athen the map considersaandbequivalent. In your case:foo{5, 0, 3} < foo{5, 3, 0}isfalsebecause5 < 5is false.foo{5, 3, 0} < foo{5, 0, 3}isfalsebecause5 < 5is false.So the map considers these objects equivalent. So
mp[{5, 3, 0}]finds the map element you just set to 1, hence it is a true value.To get the result you want, your
operator<needs to account for all three members, not justv1.For example:
or (as PaulMcKenzie suggested) more simply: