none said:
I was able to do what I wanted, but not exactly the way I would
like it to work. I choose this method because I don't want to
make 3 copies for each operators overload (int,complex), (complex,int)
and (complex,complex). This way I only have to build
a function for each operators.
COMPLEX complex;
COMPLEX complex2;
complex.real = 1;
complex.img = 3;
complex2 = (COMPLEX) 3 + complex;
complex = complex2 + (COMPLEX) 5;
complex2 = 3 + complex;
complex = complex2 + 5;
template < typename T >
class Complex
{
public:
Complex(): real(0), imag(0) { }
Complex( T r, T i ): real(r), imag(i) { }
T real;
T imag;
};
template < typename T >
Complex<T> operator+( T left, const Complex<T>& right )
{
return Complex<T>( left + right.real, right.imag );
}
template < typename T >
Complex<T> operator+( const Complex<T>& left, T right )
{
return Complex<T>( left.real + right, left.imag );
}
int main(int argc, char* argv[])
{
Complex<int> complex;
Complex<int> complex2;
complex.real = 5;
complex.imag = 2;
complex2 = 1 + complex;
assert( complex2.real == 6 );
assert( complex2.imag == 2 );
complex2 = complex + 1;
assert( complex2.real == 6 );
assert( complex2.imag == 2 );
}
error C2784: 'class Ccomplex<COMPLEXTYPE> &__cdecl operator +(class
Ccomplex<COMPLEXTYPE> &,class Ccomplex<COMPLEXTYPE> &)' : could not
deduce template argument for 'class Ccomplex<COMPLEXTYPE> &' from
'const int'
Anyone knows how I could do what I want to do?
By the way I forgot about:
int integer = complex; // integer = complex.real
because I think Daniel T. is right and it's not a smart thing
to do and can be very confusing.
here's a sample of my code :
Unfortunately, your code is riddled with errors. Try posting your actual
code and I'll be happy to review it. In general though, you are making
this way harder on yourself than it has to be. There are all kinds of
unnecessary constructs in your code, and other stuff that is missing but
must be there.
template <class COMPLEXTYPE> class Ccomplex;
template <typename COMPLEXTYPE>
inline Ccomplex<COMPLEXTYPE>& operator + (Ccomplex<COMPLEXTYPE> &dest,
\
Ccomplex<COMPLEXTYPE>
&source);
// also tried
// inline Ccomplex<COMPLEXTYPE> operator + (Ccomplex<COMPLEXTYPE>
dest, \
// Ccomplex<COMPLEXTYPE>
source);
template <class COMPLEXTYPE>
class Ccomplex
{
public:
COMPLEXTYPE real;
COMPLEXTYPE img;
// Constructor
Ccomplex (void)
{
real = 0;
img = 0;
}
// Constructor (conversion operator)
Ccomplex (COMPLEXTYPE val)
{
real = val;
img = 0;
}
// Destructor
~Ccomplex (void) { }
inline Ccomplex<COMPLEXTYPE> operator = (Ccomplex<COMPLEXTYPE>
source);
friend inline Ccomplex<COMPLEXTYPE>& operator +
(Ccomplex<COMPLEXTYPE> &dest, \
Ccomplex<COMPLEXTYPE> &source);
// also tried
// friend inline Ccomplex<COMPLEXTYPE> operator +
(Ccomplex<COMPLEXTYPE> dest, \
//
Ccomplex<COMPLEXTYPE> source);
typedef Ccomplex<int> COMPLEX;
template <class COMPLEXTYPE>
inline Ccomplex<COMPLEXTYPE> Ccomplex<COMPLEXTYPE>:
perator =
(Ccomplex<COMPLEXTYPE> source)
{
this->real = source.real;
this->img = source.img;
return *this;
}
template <typename COMPLEXTYPE>
inline Ccomplex<COMPLEXTYPE>& operator + (Ccomplex<COMPLEXTYPE> &dest,
\
Ccomplex<COMPLEXTYPE>
&source)
{
dest.real = dest.real + source.real;
dest.img = dest.img + source.img;
return dest;
}
template class Ccomplex<int>;
Spurious ';'
template Ccomplex<int>& operator + (Ccomplex<int> &dest, \
Ccomplex<int> &source);
Function above declared but not defined. It's wholly unnecessary anyway.
int main(FT_INT argc, FT_CHAR* argv[])
FT_INT and FT_CHAR were not declared. Use 'int' and 'char' instead.
{
KCOMPLEX complex;
KCOMPLEX complex2;
KCOMPLEX was not declared. I changed them to COMPLEX.
complex.real = 5;
complex.img = 2;
// WORKS
complex2 = (COMPLEX) 1 + complex;
The above doesn't work. You are creating a temporary and because your
op+ takes its parameters by non-const reference, it can't be used.
complex = complex2 + (COMPLEX) 2;
// DO NOT WORK
// error C2784: 'class Ccomplex<COMPLEXTYPE> &__cdecl operator +
(class Ccomplex<COMPLEXTYPE> &,
// class Ccomplex<COMPLEXTYPE> &)' : could not
deduce template argument for
// 'class Ccomplex<COMPLEXTYPE> &' from 'const int'
complex2 = 1 + complex;
complex = complex2 + 2;
return 0;
}- Hide quoted text -
- Show quoted text -- Hide quoted text -
- Show quoted text -- Hide quoted text -
- Show quoted text -- Hide quoted text -
- Show quoted text -
Sorry about the errors, I didn't test before posting it. Here's
a new working, cleaned and tested code. I have removed a lot
of things to make it simplier and I do not use multiple files
anymore for simplicity.
Now this code works fine like this:
COMPLEX complex1,complex2;
complex1 = 2.0 + complex2;
complex2 = complex1 + 4.0;
But I have to use a double notation to prevent compiler error
(ambiguity between int and double), I would like to be able to
write it as 1 + complex. And I also need to declare these
operator + overloads to type cast the values:
inline Ccomplex<COMPLEXTYPE> operator + \
(Ccomplex<COMPLEXTYPE> dest, const COMPLEXTYPE source);
inline Ccomplex<COMPLEXTYPE> operator + \
(const COMPLEXTYPE dest, Ccomplex<COMPLEXTYPE> source);
I'm sure there's a better way to do this, I would really like
to be able to declare only one operator overload for each
operators. By the way I think I'm may be missing some important
points about templates, I find the class and typename keywords
really confusion. Should I use typename for member types and
class only for objects? (there's no informations about
templates in any of my C++ books)
for example:
template <class COMPLEXTYPE, typename TYPENAME>
class Ccomplex
{
public:
TYPENAME real;
TYPENAME img;
...
inline Ccomplex<COMPLEXTYPE,TYPENAME> operator = \
(Ccomplex<COMPLEXTYPE,TYPENAME> source);
...
}
or am I doing it the right way?
thanks a lot for your help, your are really helpful!
// ------------------------------------------------------------
template <class COMPLEXTYPE>
class Ccomplex
{
public:
COMPLEXTYPE real;
COMPLEXTYPE img;
// Constructor
Ccomplex (void)
{
real = 0;
img = 0;
}
// Constructor (conversion operator)
Ccomplex (COMPLEXTYPE val)
{
real = val;
img = 0;
}
// Destructor
~Ccomplex (void) { }
inline Ccomplex<COMPLEXTYPE> operator = (Ccomplex<COMPLEXTYPE>
source);
friend inline Ccomplex<COMPLEXTYPE> operator + \
(Ccomplex<COMPLEXTYPE> dest, Ccomplex<COMPLEXTYPE>
source);
friend inline Ccomplex<COMPLEXTYPE> operator + \
(Ccomplex<COMPLEXTYPE> dest, const COMPLEXTYPE
source);
friend inline Ccomplex<COMPLEXTYPE> operator + \
(const COMPLEXTYPE dest, Ccomplex<COMPLEXTYPE>
source);
protected:
};
typedef Ccomplex<double> COMPLEX;
template <class COMPLEXTYPE>
inline Ccomplex<COMPLEXTYPE> \
Ccomplex<COMPLEXTYPE>:
perator = (Ccomplex<COMPLEXTYPE>
source)
{
this->real = source.real;
this->img = source.img;
return *this;
}
template <typename COMPLEXTYPE>
inline Ccomplex<COMPLEXTYPE> operator + \
(Ccomplex<COMPLEXTYPE> dest, Ccomplex<COMPLEXTYPE> source)
{
Ccomplex<COMPLEXTYPE> newdest;
newdest.real = dest.real + source.real;
newdest.img = dest.img + source.img;
return newdest;
}
template <typename COMPLEXTYPE>
inline Ccomplex<COMPLEXTYPE> operator + \
(Ccomplex<COMPLEXTYPE> dest,const COMPLEXTYPE source)
{ return dest + (Ccomplex<COMPLEXTYPE>) source; }
template <typename COMPLEXTYPE>
inline Ccomplex<COMPLEXTYPE> operator + \
(const COMPLEXTYPE dest, Ccomplex<COMPLEXTYPE> source)
{ return (Ccomplex<COMPLEXTYPE>) dest + source; }
int main(int argc, char* argv[])
{
COMPLEX complex;
COMPLEX complex2;
complex.real = 5;
complex.img = 2;
// WORKS
complex2 = (COMPLEX) 1 + complex;
complex = complex2 + (COMPLEX) 2;
// WORKS but must use double notation to avoid
// template ambiguities between in and double
complex2 = 1.0 + complex;
complex = complex2 + 2.0;
return 0;
}