A map
considers two Keys equal if neither a < b
nor b < a
is true.
mymap[Fraction(100, 100)] = 1;
mymap[Fraction(200, 200)] = 2;
The first fraction is 100/100
and the second is 200/200
and neither 100/100 < 200/200
nor 200/200 < 100/100
is true mathematically. You are not using integer division to do the comparison though, so lets check num * rhs.den < den * rhs.num;
or 100*200 < 200*100
and the same applies there.
- Neither
100*200 < 200*100
nor 200*100 < 100*200
is true - so they are considered equal.
This is why you in mymap[Fraction(200, 200)] = 2;
overwrite the value stored by mymap[Fraction(100, 100)] = 1;
and there is only one Key fraction in your map.
I noted that you said "I added additional check in operator<
in order to distinguish the two cases" in the comments. This is probably a mistake since it will break the expectations users of your Fraction
class will have. Consider this snippet:
Fraction a(100, 100);
Fraction b(200, 200);
if(a < b) {
// should not happen
} else if(b < a) {
// should not happen
} else {
// the expected
}
If you've modified operator<
to be able to use both a
and b
as Keys in your map
, then one of the two "should not happen" cases will kick in.
Alternatives:
- Use a
std::multimap
where multiple Keys considered equal can be stored. This will however change your mapping so that multiple 100/100
Keys can be stored, not only both 100/100
and 200/200
.
- Use a
std::map
with a custom comparator:
struct FractionCmp {
bool operator()(const Fraction& lhs, const Fraction& rhs) const {
if(lhs < rhs) return true;
if(rhs < lhs) return false;
// they are really equivalent, but:
return lhs.num < rhs.num;
}
};
std::map<Fraction, int, FractionCmp> mymap;