TLDR; I want to use operators defined for my class with primitive data types that can be converted into my class without typecasting/initializing new variables. i.e.,
mycomplex x = 5 , y ;
y = x + 3 ;
As a side project, I am developing a complex number class. For obvious reasons, any primitive numeric data type can be interpreted as a complex number. Therefore, in any operation involving a primitive type and a complex, I would like to allow the primitive type to convert to a complex and continue the operation using my defined operations involving two complex numbers.
Each primitive type can be overloaded on each operator, but order matters, and with 4 basic operators and a few higher math functions it is quickly going to turn into alot of code. So the question is, how to write my class such that a primitive type will "cast" to a complex and perform normal complex operations.
This code compiles if the second to last line of main is commented out. Getting that line to evaluate to a mycomplex with cout of 8+2i is the goal here.
#include <iostream>
template <class T>
class mycomplex{
private:
T real ;
T imag ;
public:
mycomplex( const mycomplex<T> & x ) ;
mycomplex( const T & realx , const T & imagx ) ;
mycomplex( const T & x ) ;
mycomplex( ) ;
template <class U>
friend std::ostream & operator << ( std::ostream & os , const mycomplex<U> & x ) ;
template <class U>
friend mycomplex<U> operator + ( const mycomplex<U> & lhs , const mycomplex<U> & rhs ) ;
} ;
int main( int argc , char * argv[] ){
mycomplex<float> x = 5 , y( 3 , 2 ) ;
mycomplex<float> z = y + x ;
std::cout << x << '\n' << y << '\n' << z << std::endl ;
z = 5 + y ;
return 0 ;
}
template <class T>
mycomplex<T>::mycomplex( const mycomplex<T> & x ){
real = x.real ;
imag = x.imag ;
}
template <class T>
mycomplex<T>::mycomplex( const T & realx , const T & imagx ){
real = realx ;
imag = imagx ;
}
template <class T>
mycomplex<T>::mycomplex( const T & x ){
real = x ;
imag = 0 ;
}
template <class T>
mycomplex<T>::mycomplex( ){
real = 0 ;
imag = 0 ;
}
template <class T>
std::ostream & operator << ( std::ostream & os , const mycomplex<T> & x ){
os << x.real ;
if( x.imag >= 0 )
os << "+" ;
os << x.imag << "i" ;
return os ;
}
template <class T>
mycomplex<T> operator + ( const mycomplex<T> & lhs , const mycomplex<T> & rhs ){
mycomplex<T> ans ;
ans.real = lhs.real + rhs.real ;
ans.imag = lhs.imag + rhs.imag ;
return ans ;
}
I looked at this answer and implemented that as you can see above, but that doesn't let this compile though it is handy for when you declare variables. I also looked at this answer and added a type-cast to the template type, but that causes my class to go to the template, which is exactly the opposite of the goal. It allows the above code to compile but any mycomplex + T gives a mycomplex without an imaginary part, which is not correct.