TLDR; Я хочу использовать операторы, определенные для моего класса, с примитивными типами данных, которые могут быть преобразованы в мой класс без приведения типов / инициализации новых переменных. т.е.
mycomplex x = 5 , y ;
y = x + 3 ;
В качестве побочного проекта я занимаюсь разработкой класса комплексных чисел. По понятным причинам любой примитивный числовой тип данных может интерпретироваться как комплексное число. Поэтому в любой операции, включающей примитивный тип и комплекс, я бы хотел, чтобы примитивный тип преобразовывался в комплекс и продолжал операцию, используя мои определенные операции, включающие два комплексных числа.
Каждый тип примитива может быть перегружен на каждом операторе, но порядок имеет значение, и с 4 базовыми операторами и несколькими более высокими математическими функциями он быстро превратится во много кода. Поэтому вопрос в том, как написать мой класс таким образом, чтобы примитивный тип "приводил" к сложному и выполнял обычные сложные операции.
Этот код компилируется, если закомментирована вторая-последняя строка main. Цель состоит в том, чтобы получить эту строку для mycomplex с cout 8 + 2i.
#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 ;
}
Я посмотрел на этот ответ и реализовал его, как вы можете видеть выше, но это не позволяет компилировать его, хотя это удобно при объявлении переменных. Я также посмотрел на этот ответ и добавил приведение типа к типу шаблона, но это заставляет мой класс перейти к шаблону, что в точности противоположно цели. Это позволяет скомпилировать приведенный выше код, но любой mycomplex + T дает mycomplex без мнимой части, что неверно.