До этого я писал в visual studio, и ничего такого не требовалось.
Вы что-то выдумываете. Это требуется всегда и везде по совершенно очевидным и естественным причинам: шаблон - это фактически усовершенствованный "макрос".
Погодите, разве это не костыль? Смысл же шаблона в том, что я не знаю какой будет использоваться тип данных, а тут я явно указываю, что это - int.
Совершенно верно. В таком применении это - костыль и делать так не нужно.
Эта фича языка (явное инстанцирование) предназначена совсем для других целей: для ускорения компиляции шаблона для какого-то фиксированного (и часто используемого) набора заранее известных аргументов. Явное инстанцирование не предназначено для решения вашей исходной проблемы.
Все определения шаблона должно быть видны везде, где они используются. То есть определения шаблонов нельзя делить на .h и .cpp файлы. Все целиком должно располагаться в .h файле.
Я дописал operator >> и operator <<. Выдается та же самая ошибка
Я не вижу этого в приведенном на данный момент коде, но мой дар ясновидения подсказывает мне, что это уже совсем другая ошибка. Вы на самом деле определили не тот оператор, который объявили, потому и получаете ошибки линковки. Это очень распространённая ошибка при определении "друзей" для шаблонных классов.
Простейший вариант решения этой проблемы: поместите определения этих операторов прямо в класс, прямо туда где вы их объявили. Более того (не вдаваясь в детали): для того варианта объявления friend-функции шаблона класса, который вы использовали в вашем коде,
в С++ невозможно предоставить определение за пределами определения шаблона класса - для этого в С++ просто не существует синтаксиса.