тип возврата decltype(auto) у перегруженного оператора шаблонного класса

У меня есть шаблонный класс Matrix у которого я перегружаю оператор умножения числа на матрицу:

class Matrix {
private:
        T* m_ptr;
        int m_rows;
        int m_columns;

//какой то код

Matrix(int rows, int cols) { // конструктор, использующийся в операторе
            if (rows < 0) {
                throw std::runtime_error("Rows at least zero!");
            }
            if (cols < 0) {
                throw std::runtime_error("Cols at least zero!");
            }
            m_ptr = new T[static_cast<long long>(rows) * cols];
            m_rows = rows;
            m_columns = cols;
        }


//какой-то код


template<typename X, typename T1>
        friend decltype(auto) operator*(X x, const Matrix<T1>& m) {
            Matrix ans(m.rows(), m.columns());
            for (int i = 0; i < m.m_columns * m.m_rows; i++) {
                ans.m_ptr[i] = m(i/m.columns(), i%m.columns()) * x;
            }
            return ans;
        }

При попытке скомпилировать следующий код ловлю ошибку компиляции:

std::cout << 3.14 * m_i << std::endl;

Ошибка C2995 decltype(auto) linalg::operator *(X,const linalg::Matrix<T1> &): шаблон функции уже определен

Я абсолютно уверен, что это единственное определение этого оператора.

Кто-нибудь знает почему так происходит?


Ответы (1 шт):

Автор решения: isnullxbh

Ошибка возникает из-за того, что при каждом инстанцировании шаблона классов Matrix [с очередным типом], появляется очередное определение оператора *. И так как оно ничем не отличается от предыдущего (см. сигнатуру), компилятор выдает ошибку.

Matrix<int>    m1 {}; // Ок
Matrix<double> m2 {}; // Ошибка, попытка определить * второй раз
→ Ссылка