as a part of my uni task I need to write class for rational numbers, override math operator, compare operators, etc. But I also need to overload cast to short, int and long types. Here is simplified code for my class:
class RationalNumber {
long long numerator, divider;
public:
RationalNumber() : numerator(0), divider(1) {}
RationalNumber(long long numerator, long long divider = 1) : numerator(numerator), divider(divider) {}
// Let's take only one math operator
RationalNumber operator*(const RationalNumber& other) {
return { numerator * other.numerator, divider * other.divider };
}
// And one cast operator
operator int() {
return numerator / divider;
}
//...
};
The problem is, if I now want to multiply RationalNumber object by int, I'll get an error saying this operation is ambiguous:
int main() {
int integer = 2;
RationalNumber rational(1, 2);
rational * integer;
// Well, ambiguous:
// 1. Cast 'rational' to int and multiply. Or
// 2. Cast 'integer' to RationalNumber and RationalNumber::operator*
return 0;
}
Adding constructor specifically for single int -- dosen't work. The thing that Does work -- adding RationalNumber::operator*(int). Problem with this approach is: I need to override ALL math operations, compare operations, etc, for int since I have cast operator to int -- operator int.
Ok, but even if I'll do that, the second I try to use unsigned compiler will bombard me with tons of warnings about casting unsigned to int and potential data loss (thought it will compile):
class RationalNumber {
//...
public:
//...
RationalNumber operator*(int othNum) {
return { numerator * othNum, divider };
}
//...
};
int main() {
unsigned int uinteger = 2;
RationalNumber rational(1, 2);
rational * uinteger; // Well... AAAAAAA
return 0;
}
test.cpp: In function ‘int main()’:
test.cpp:29:14: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
29 | rational * integer;
| ^~~~~~~
test.cpp:14:18: note: candidate 1: ‘RationalNumber RationalNumber::operator*(int)’
14 | RationalNumber operator*(int othNum) {
| ^~~~~~~~
test.cpp:29:14: note: candidate 2: ‘operator*(int, unsigned int)’ (built-in)
29 | rational * integer;
|
To completely satisfy compiler I need to add RationalNumber::operator*(unsigned). Now let's remember that I need to overload 3 casting operators and a dozen of math/compare operators. Which means I need to create 6 extra functions for EACH operator overload.
So, can I somehow force compiler to always cast values in favor of my class?