|
-
February 14th, 2007, 02:45 PM
#1
basic class templates, confusion!
Hello everyone...i'm not sure why this isn't working...
what i'm trying to do is do the following:
Code:
Complex<int> a(3,10);
Complex<float> b(3.4,30.2);
cout << a + b << endl;
I have it so my class will work if i just use 2 of the same types like
Code:
Complex<int> a(3,2); Complex<int> b(20,3);
cout << a + b << endl;
That will run fine.
Well here is my code:
Code:
// Complex.h
#pragma once
#include <iostream>
using namespace std;
//you can have template <typename T, typename B>
// template <typename T, SIZE> size is now a constant
template <typename T> class Complex
{
public:
// default constructor
Complex()
{
Real = Imaginary = 0.0;
}
Complex(T real, T imag)
{
this->Real = real;
this->Imaginary = imag;
}
// copy constructor
Complex(const Complex& c)
{
Real = c.Real;
Imaginary = c.Imaginary;
}
T Real;
T Imaginary;
// overloading +
Complex operator +(const Complex& c)
{
return Complex(Real + c.Real, Imaginary + c.Imaginary);
}
template <typename T> Complex<T> operator +(const Complex<T> & c)
{
return Complex(Real + c.Real, Imaginary + c.Imaginary);
}
Complex operator +(const T b)
{
return Complex(Real + b, Imaginary);
}
// overload -
Complex operator-(const Complex & c)
{
return Complex(Real - c.Real, Imaginary - c.Imaginary);
}
// overloading =
template <typename T> Complex<T> operator=(const Complex<T> & c)
{
return Complex(Real = c.Real, Imaginary = c.Imaginary);
}
template <typename T> Complex<T>& operator+=(const Complex<T> & c)
{
Real += c.Real;
Imaginary += c.Imaginary;
return *this;
//you take a value from a source and you assign
//it to the destination, you destroied the oringal data
//so you must return a oginal value to it
}
//allow a floating point to be added to the complex
/*Complex& operator+=(const T real)
{
Real += real;
return *this;
}*/
/*allow a floating point to be added with +
Complex operator+ (T num)
{
return Complex(Real+num, Imaginary );
}*/
Complex operator * (const Complex &c)
{
return Complex(this->Real*c.Real - this->Imaginary*c.Imaginary,
this->Real*c.Imaginary + this->Imaginary*c.Real);
}
template <typename T> Complex<T>* FFT(Complex<T>* data, int size)
{
return data;
}
};
template <typename T>ostream& operator << (ostream& out, const Complex<T>& c)
{
out << "(" << c.Real << "," << c.Imaginary << ")";
return out;
}
I'm getting the following errror and its pointing to this chunk of code:
Code:
template <typename T> Complex<T> operator +(const Complex<T> & c)
{
return Complex(Real + c.Real, Imaginary + c.Imaginary);
}
its saying:
Code:
(55) : error C2664: 'Complex<T>::Complex(const Complex<T> &)' : cannot convert parameter 1 from 'Complex<T>' to 'const Complex<T> &'
1> with
1> [
1> T=float
1> ]
1> and
1> [
1> T=long double
1> ]
1> and
1> [
1> T=float
1> ]
1> Reason: cannot convert from 'Complex<T>' to 'const Complex<T>'
1> with
1> [
1> T=long double
1> ]
1> and
1> [
1> T=float
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
I've looked up a few tutorials and have no idea what i'm not doing right, i nkow i have to do a specialized function if i want to add 2 different class types <int> and <float> but i don't see what i'm messing up on..
Thanks!
-
February 14th, 2007, 02:59 PM
#2
Re: basic class templates, confusion!
 Originally Posted by voidflux
Hello everyone...i'm not sure why this isn't working...
what i'm trying to do is do the following:
Code:
Complex<int> a(3,10);
Complex<float> b(3.4,30.2);
A Complex<int> and a Complex<float> are two different types. That's the reason for the error.
Using Complex<> doesn't make them the same thing. A template is defined by the types used in the template arguments, not just the template name.
Regards,
Paul McKenzie
-
February 14th, 2007, 03:11 PM
#3
Re: basic class templates, confusion!
Thanks Paul, I know the issue there thats why i was trying to make my + operator work in all cases even if i'm adding 2 different class types, in this case <int> and <float> with this function:
Code:
template <typename T> Complex<T> operator +(const Complex<T> & c)
{
return Complex(Real + c.Real, Imaginary + c.Imaginary);
}
if i wanted to add 2 of the same type of class, i could just use this:
Code:
...
...
T Real;
T Imaginary;
// overloading +
Complex operator +(const Complex& c)
{
return Complex(Real + c.Real, Imaginary + c.Imaginary);
}
But i would like to add 2 different class types, or is this impossible/
-
February 14th, 2007, 03:20 PM
#4
Re: basic class templates, confusion!
Hello,
Try this:
Code:
return Complex<T>(Real + c.Real, Imaginary + c.Imaginary);
instead of:
Code:
return Complex(Real + c.Real, Imaginary + c.Imaginary);
ZDF
What is good is twice as good if it's simple.
"Make it simple" is a complex task.
-
February 14th, 2007, 03:23 PM
#5
Re: basic class templates, confusion!
oh man somsone was ahead ofme.
just as zdf says.
-
February 14th, 2007, 03:36 PM
#6
Re: basic class templates, confusion!
Awesome! thanks so much that worked perfect, i'm trying to now get += to work, like:
Code:
Complex<long double> f(10.0,20.0);
Complex<float> g(11.0,22.0);
f += g;
I fixed the = by doing as u mention above with:
Code:
// overloading =
template <typename T> Complex<T> operator=(const Complex<T> & c)
{
return Complex<T>(Real = c.Real, Imaginary = c.Imaginary);
}
But how would I incoperate a <T> in the following:
Code:
template <typename T> Complex<T>& operator+=(const Complex<T> & c)
{
Real += c.Real;
Imaginary += c.Imaginary;
return *this;
//you take a value from a source and you assign
//it to the destination, you destroied the oringal data
//so you must return a oginal value to it
}
I can't think of anyother way to refer to the current object
Putting a T in return <T>*this would flag an error becuase it makes no senes :P
-
February 14th, 2007, 03:50 PM
#7
Re: basic class templates, confusion!
hi this should be fine:
Code:
template <typename T> Complex& operator+=(const Complex<T> & c)
{
Real += c.Real;
Imaginary += c.Imaginary;
return *this;
//you take a value from a source and you assign
//it to the destination, you destroied the oringal data
//so you must return a oginal value to it
}
-
February 14th, 2007, 06:41 PM
#8
Re: basic class templates, confusion!
Thanks for the responce but with that code i get:
Code:
(84) : error C2440: 'return' : cannot convert from 'Complex<T>' to 'Complex<T> &'
1> with
1> [
1> T=long double
1> ]
1> and
1> [
1> T=float
1> ]
1> ..\..\..\..\cse122\Complex template\test.cpp(14) : see reference to function template instantiation 'Complex<T> &Complex<long double>::operator +=<float>(const Complex<T> &)' being compiled
1> with
1> [
1> T=float
1> ]
from the following code:
Code:
Complex<long double> f(10.0,20.0);
Complex<float> g(11.0,22.0);
f += g;
And its pointing to the return *this statement;
-
February 14th, 2007, 11:46 PM
#9
Re: basic class templates, confusion!
Mixing the complex classes like this does not seem necessary. Moreover, arithematic op operators should be implemented in terms of op=. For example, operator+ in terms of operator+=. Here operator+= should be a member and operator+, a non-member (not required to make it a friend even).
If mixing types is justified in your case, what you can do is, add non-members such as:
Code:
template<typename T, typename U>
Complex<T> operator+(const Complex<T>& lhs, const Complex<U> rhs)
{
return Complex<T>(lhs)+=rhs;
}
Now, the member operator+= would be implemented as a member template as:
Code:
template<typename T>
class Complex
{
//other members
T real;
T imaginary;
public:
template<typename U>
Complex<T>& operator+=(const Complex<U> rhs)
{
real+=rhs.real;
imaginary+=rhs.imaginary;
return *this;
}
};
Take a look at the FAQ I posted on operator overloading.
Can you help me with my homework assignment?, Before you post!, Use code tags, How to post!, Codeguru technical FAQs, C++ FAQ Lite, Stroustrup: C++ Style and Technique FAQ, Guru of the Week, Comeau C and C++ FAQs, Comeau C++ Templates FAQs, CUJ @ DDJ, Spam threshold
My Blogs : Learning C++ is fun | Abnegator's reflections
Open Threads : C++ Aha! Moments | Nature of work in C++?
-
February 15th, 2007, 12:14 AM
#10
Re: basic class templates, confusion!
Oooo that does make alot more sense the way your doing it, thanks
-
February 15th, 2007, 06:38 AM
#11
Re: basic class templates, confusion!
 Originally Posted by exterminator
Mixing the complex classes like this does not seem necessary. Moreover, arithematic op operators should be implemented in terms of op=. For example, operator+ in terms of operator+=. Here operator+= should be a member and operator+, a non-member (not required to make it a friend even).
If mixing types is justified in your case, what you can do is, add non-members such as:
Code:
template<typename T, typename U>
Complex<T> operator+(const Complex<T>& lhs, const Complex<U> rhs)
{
return Complex<T>(lhs)+=rhs;
}
Now, the member operator+= would be implemented as a member template as:
Code:
template<typename T>
class Complex
{
//other members
T real;
T imaginary;
public:
template<typename U>
Complex<T>& operator+=(const Complex<U> rhs)
{
real+=rhs.real;
imaginary+=rhs.imaginary;
return *this;
}
};
Take a look at the FAQ I posted on operator overloading.
your second is what i was trieing to say..
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|