У вас несоответствие в натуральном выражении.
Ваша первоначальная декларация и последующее определение имеют эту подпись:
template<typename T, int N>
Matrix<N> operator*(const Matrix<N> &m1, const T &m2);
Это шаблон функции, принимающий два параметров шаблона: T
и N
.
Однако в вашем классе вы создаете в качестве друга шаблон функции с такой подписью:
template<typename T>
friend Matrix<N> operator* (const Matrix<N> &m1, const T &m2);
Имеется только один параметр шаблона: T
. N
здесь зафиксировано. Это объявление друга также объявляет этот шаблон функции. Это лучшее соответствие, но на самом деле не определено, отсюда и поведение, которое вы видите.
<ч />
Думаю, у вас есть два варианта.
Удалите объявление области имен пространства operator*
и просто объявите и определите friended operator*
в определении Matrix
.
Измените объявление друга, чтобы оно соответствовало объявлению пространства имен:
template<typename T, int M>
friend Matrix<M> operator* (const Matrix<M> &m1, const T &m2);
(1), как правило, является лучшим вариантом - не требует добавления большего числа operator*
в глобальную область видимости, что хорошо для времени компиляции.