Добрый день, задача: написать шаблонный класс рациональных чисел с перегрузкой сокращения дроби.
Для варианта, когда числитель и знаменатель изначально везде типа int, всё работает. 
Проблема в том, чтоб сделать этот класс именно шаблонным.
Сейчас выводит такие ошибки: 
error LNK2019: ссылка на неразрешенный внешний символ "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl operator>>(class std::basic_istream<char,struct std::char_traits<char> > &,class rat<int> &)" (??5@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV01@AAV?$rat@H@@@Z) в функции _main
error LNK2019: ссылка на неразрешенный внешний символ "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class rat<int> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$rat@H@@@Z) в функции _main
 fatal error LNK1120: неразрешенных внешних элементов: 2
Код написан в Visual Studio:
#include <iostream>
using namespace std;
template <class T> 
class rat{
	T ch, zn;
public:
	friend istream& operator>>(istream& stream_in, rat<T> &rvalue); 
	friend ostream& operator<<(ostream& stream_out,const rat<T> &rvalue); 
	T nod(T, T);  // наибольший общий делитель 
	T abs(T); // модуль числа 
	rat(int = 0, int = 1); 
	void norm(); // для сокращения дроби  
};
template <class T> T rat <T>::abs(T x) {
	if (x < 0)
		return (-1)*x;
	return x;
}
template <class T> T rat <T>::nod(T x, T y) { 
	if (x == 0 || y == 0)
		return 1;
	while (x != y)
		if (x > y)
			x = x - y;
		else
			y = y - x;
	return x;
}
template <class T> rat <T>::rat(int x, int y) { 
	if (!y || !x) {
		ch = 0;
		zn = 1;
	}
	ch = x;
	zn = y;
	this->norm();
}
template <class T> void rat <T>::norm() {  
	int sign = 1;
	if (ch*zn < 0)
		sign = (-1);
	ch = abs(ch);
	zn = abs(zn);
	T b = nod(ch, zn);
	if (ch == 0 || zn == 0)
		zn = 1; 
	if (b == 1)
		return;
	ch = (ch / b)*sign;
	zn = zn / b;
}
template <class T> istream& operator>>(istream& stream_in, rat<T> &rvalue) {
	cout << "Enter rational value (a/b): ";
	stream_in >> rvalue.ch;
	stream_in.ignore();
	stream_in >> rvalue.zn;
	cout << endl;
	return stream_in;
};
template <class T> ostream& operator<<(ostream& stream_out,const rat<T> &rvalue) {
	stream_out << "Rational number: " << rvalue.ch << "/" << rvalue.zn << endl;
	return stream_out;
}
int main() {
	rat <int> a;
	cin >> a;  
	cout <<  a  << endl;
	return 0;
}