I've run into something I don't understand in regards to a class I've built and how it interacts with built-in types through operator overloading in C++. As an example of my problem below is a (incomplete) complex number class:
class complex {
public:
complex(double real=0., double imag=0.) : _real(real), _imag(imag) {;}
~complex() {;}
complex& operator=(const complex &rhs) {
if(this!=&rhs) {
this->_real = rhs._real;
this->_imag = rhs._imag;
}
return *this;
}
complex& operator*=(const complex &rhs) {
this->_real = this->_real * rhs._real + this->_imag * rhs._imag;
this->_imag = this->_real * rhs._imag + this->_imag * rhs._real;
return *this;
}
const complex operator*(const complex &other) const {
complex result = *this;
result *= other;
return result;
}
protected:
double _real;
double _imag;
};
When I call this code with the following main:
int main(void)
{
complex a(1.,0.);
complex b;
b = a * 2.;
b = 2. * a;
return 0;
}
I get the complier error for the second to last line in "main.cpp":
error: no match for ‘operator*’ in ‘2.0e+0 * a’
but no error for the line before. If I cast the "2.0" in the offending line to a complex then all is good. So my question is, how/why does the compiler know to cast the double to a complex number in the first line but (appears to ) want to use the double version of the operator* in the second line?
If I could derive a class, say Real, that derives off of double and adds something like:
const complex operator*(const double &other)
then I think this would work but I know I can't do that (built-in types can't be used as base-classes).
Thanks!
@MikeSeymore had a nice fix. Add a non-member function. What I ended up with was:
complex operator*(double lhs, complex const &rhs) {
complex result(lhs,0.);
return result*=rhs;
}
and all is good with the world. Thanks Mike.
BTW: A discussion of non-class overloading Operator overloading outside class