Reputation: 1738
#include <iostream>
using namespace std;
class StringNum {
public:
string s;
StringNum() {s = "";}
public:
StringNum(int n) {
for (int i=1; i<=n; i++) s += "x";
}
operator int () {
return s.length();
}
StringNum operator - (StringNum v) {
int len = s.length() - v.s.length();
StringNum res;
for (int i=1;i<=len;i++) res.s += "x";
return res;
}
/* // long solution. But this will allow the program to run.
template <class T>
StringNum operator - (T value) {
return (*this) - StringNum(value);
}
*/
};
int main()
{
StringNum x(4);
cout << 3 - x; // this compiles
cout << x - 3; // error: ambiguous overload for operator -
// change the program so that the 2nd line output 2
return 0;
}
So I have a class that can be upcast from int/downcast to int (this is the simplified version, in the actual version StringNum is HighPrecisionFloat, and int is int/float/double/.. . etc).
When I compile the program, the error message
In function 'int main()':|
error: ambiguous overload for 'operator-' (operand types are 'StringNum' and 'int')|
note: candidate: operator-(int, int) <built-in>|
note: candidate: StringNum StringNum::operator-(StringNum)|
This happens because there are 2 ways to understand x - 3
:
a) int(x) - 3
b) x - StringNum(3)
One way to do this is to use template for each operator (+, -, *, /, dot product, etc...) But that is not very convenient because I have to write templates for each operator.
Is there a better solution to this problem? I wish to call x - StringNum(3).
Thank you.
Upvotes: 0
Views: 234
Reputation: 2850
You can make your constructor and conversion to int explicit
.
The compiler won't make implicit conversion between those types anymore, but you can still use them like so.
auto stringNum = StringNum{3}; //int to StringNum
int y = static_cast<int>(stringNum);
Upvotes: 1