CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Sep 2004
    Posts
    236

    Arrow 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!
    Computer Science/Engineering
    @ PSU
    Co-oping with IBM's zSeries team! wee
    VS 2005.net
    http://www.personal.psu.edu/css204/

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: basic class templates, confusion!

    Quote 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

  3. #3
    Join Date
    Sep 2004
    Posts
    236

    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/
    Computer Science/Engineering
    @ PSU
    Co-oping with IBM's zSeries team! wee
    VS 2005.net
    http://www.personal.psu.edu/css204/

  4. #4
    Join Date
    Jun 2002
    Posts
    224

    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.

  5. #5
    Join Date
    Aug 2005
    Location
    Netherlands, The
    Posts
    2,184

    Re: basic class templates, confusion!

    oh man somsone was ahead ofme.

    just as zdf says.

  6. #6
    Join Date
    Sep 2004
    Posts
    236

    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
    Computer Science/Engineering
    @ PSU
    Co-oping with IBM's zSeries team! wee
    VS 2005.net
    http://www.personal.psu.edu/css204/

  7. #7
    Join Date
    Aug 2005
    Location
    Netherlands, The
    Posts
    2,184

    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
    	}

  8. #8
    Join Date
    Sep 2004
    Posts
    236

    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;
    Computer Science/Engineering
    @ PSU
    Co-oping with IBM's zSeries team! wee
    VS 2005.net
    http://www.personal.psu.edu/css204/

  9. #9
    Join Date
    Feb 2005
    Location
    "The Capital"
    Posts
    5,306

    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.

  10. #10
    Join Date
    Sep 2004
    Posts
    236

    Re: basic class templates, confusion!

    Oooo that does make alot more sense the way your doing it, thanks
    Computer Science/Engineering
    @ PSU
    Co-oping with IBM's zSeries team! wee
    VS 2005.net
    http://www.personal.psu.edu/css204/

  11. #11
    Join Date
    Aug 2005
    Location
    Netherlands, The
    Posts
    2,184

    Re: basic class templates, confusion!

    Quote 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
  •  





Click Here to Expand Forum to Full Width

Featured