4

I'm new to C++ and I'm trying to use template but I got problems. What I'm trying to do is: try to calculate square of a number using template, and the number may be basic data types like int, float, as well as complex numbers. I also implemented a complex class using template, and the codes are as follows:

template <typename T>
class Complex {
public:
  T real_;
  T img_;

  Complex(T real, T img) : real_(real), img_(img) { } 
};

template <typename T>
T square(T num) {
  return num * num;
}

template <>
Complex<typename T> square(Complex<typename T> num) {
  T temp_real = num.real_*num.real_ - num.img_*num.img_;
  T temp_img  = 2 * num.img_ * num.real_;
  return Complex(temp_real, temp_img);
}

I tried to use template specialization to deal with the special case, but it gave me error:

using ‘typename’ outside of template

and the error happens on the template specialization method. Please point out my mistakes. Thanks.

Shang Wang
  • 24,909
  • 20
  • 73
  • 94
  • Not an answer, but be advised of the `` header which possibly obviates the need for any code altogether. – Kerrek SB Jul 12 '11 at 01:43

1 Answers1

6

It appears that you're trying to partially specialize function templates, which isn't actually possible in C++. What you want instead is to simply overload the function like this:

template<typename T>
T square(T num) // Overload #1
{ 
    return num * num;
}

template<typename T>
Complex<T> square(Complex<T> num) // Overload #2
{
    T temp_real = num.real_*num.real_ - num.img_*num.img_;
    T temp_img  = 2 * num.img_ * num.real_;
    return Complex<T>(temp_real, temp_img);
}

Informally, the compiler will always pick overload #2 over overload #1 when the argument is of type Complex<T> because it's a better match.


Another way to make this work is to overload the multiplication operator for the Complex<> class using the definition of multiplication for complex numbers. This has the advantage of being more general and you can extend this idea to other operators.

template <typename T>
class Complex
{
public:
    T real_; 
    T img_; 

    Complex(T real, T img) : real_(real), img_(img) {} 

    Complex operator*(Complex rhs) // overloaded the multiplication operator
    {
        return Complex(real_*rhs.real_ - img_*rhs.img_,
            img_*rhs.real_ + real_*rhs.img_);
    }
};

// No overload needed. This will work for numeric types and Complex<>.
template<typename T>
T square(T num)
{
    return num * num;
}

Since you are new to C++, I highly recommend that you pick up a good introductory C++ book. Templates and operator overloading aren't exactly beginner's topics.

Community
  • 1
  • 1
In silico
  • 51,091
  • 10
  • 150
  • 143