Этот
template <T, int num1, int num2 > friend Stack<T, num1>& operator+(Stack<T, num1>& s1, const Stack<T, num2>& s2);
объявляет шаблон функции operator+
, который принимает значение типа T
, значение типа int
и другое значение типа int
в качестве параметров шаблона как друг вашего класса шаблона. Обратите внимание, что шаблон функции, который вы объявили другом, не тот, который вы объявили выше определения Stack
. Списки аргументов шаблона отличаются. Выше определения Stack
вы объявляете:
template <class T, int num1, int num2>
// ^ type parameter
Stack<T, num1>& operator+(Stack<T, num1>& s1, const Stack<T, num2>& s2);
, но в объявлении друга вы объявляете
template <T, int num1, int num2>
// ^ non-type parameter
Stack<T, num1>& operator+(Stack<T, num1>& s1, const Stack<T, num2>& s2);
Вам нужно будет написать
template <class U, int num1, int num2> friend Stack<U, num1>& operator+(Stack<U, num1>& s1, const Stack<U, num2>& s2);
сделать свой оригинальный шаблон operator+
другом шаблона класса Stack
…
Помимо всего этого, я бы порекомендовал вам остановиться и подумать, действительно ли это хорошая идея, что выражение типа
a + b
неявно изменяет a
. Если вам действительно нужно использовать оператор для этого, operator+=
, вероятно, является лучшим способом express этой семантики (лично я, вероятно, просто придерживаюсь здесь функции добавления). Так как operator+=
должна быть нестатической c функцией-членом, ваша первоначальная проблема также исчезнет ...