c++templatesoperator-overloadingfriend-function

"undefined reference to `operator>>(std::istream&, Complex<int>&)" for template Complex<T>


My code:

#include <iostream>
using std::cin;
using std::cout;
using std::istream;
using std::ostream;

template<typename T>
class Complex
{
    T real, img;
public:
    Complex():real(0), img(0){}
    friend istream& operator>>(istream& input, Complex& c1);
    friend ostream& operator<<(ostream& output, Complex& c1);
    Complex operator+(Complex& c1);
};

template<typename T>
istream& operator>>(istream& input, Complex<T>& c1)
{
    cout<<"Real: ";
    input>>c1.real;
    cout<<"Imag: ";
    input>>c1.img;
    return input;
}

template<typename T>
ostream& operator<<(ostream& output, Complex<T>& c1)
{
    output<<c1.real<<"+"<<c1.img<<"i";
    return output;
}

template<typename T>
Complex<T> Complex<T>::operator+(Complex<T>& c1)
{
    Complex temp;
    temp.real = this->real + c1.real;
    temp.img = this->img + c1.img;
    return temp;
}

int main()
{
    Complex<int> cmp1;
    cin>>cmp1;
    return 0;
}

The error I'm getting is at cin>>cmp1 which is undefined reference to 'operator>>(std::istream&, Complex<int>&)'. But I can't find anything wrong in my code.

The code works if I make complex a non-template class which uses double and remove all template-related code, so the definition of operator>>() is essentially correct.

What changes when I make Complex a template?


Solution

  • Friend functions are not members so they aren't implicitly templates. Declaration there suggests existence of non-template operator for instantiated type Complex<int>. You may use

    template<typename U> 
    friend istream& operator>>(istream& input, Complex<U>& c1);
    
    template<typename U> 
    friend ostream& operator<<(ostream& output, Complex<U>& c1);