I am working on two wrapper classes that define real and complex data types. Each class defines overloaded constructors, as well as four arithmetic operators +, -, *, / and five assignment operators =, + =, etc. To avoid code repetition, I was thinking about using template functions when the left and right arguments of the operator have a different data type:
class Real {
public:
explicit Real(const double& argument) {...}
explicit Real(int argument) {...}
...
friend const operator*(const Real&; const Real&);
template <class T> friend const Real operator*(const Real&, const T&);
template <class T> friend const Real operator*(const T&, cont Real&);
};
class Complex {
public:
explicit Complex(const Real& realPart) {...}
explicit Complex(const Real& realPart, const Real& imaginaryPart) {...}
...
friend const operator*(const Complex&, const Complex&);
template <class T> friend const Complex operator*(const Complex&, const T&);
template <class T> friend const Complex operator*(const T&, cont Complex&);
...
};
The problem here is that the code is like:
void main() {
Complex ac(2.0, 3.0);
Real br(2.0);
Complex cc = ac * br;
}
the compiler ( gcc ) returns an ambiguous overload error for 'operator *' in 'ac * br' , because the compiler cannot determine the difference between:
template <class T> friend const Complex operator*(const Complex&, const T&) [with T = Real]template <class T> friend const Real operator*(const T&, cont Real&) [with T = Complex]
, T * Real? ? ?