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;