模板类的标量乘法不起作用

范怀尔德

当我进行标量乘法时会发生此错误。我正在使用模板类对矩阵执行这些操作。我一直试图掌握这些概念,但我似乎失败了。任何帮助表示赞赏。

main.cpp 里面的 main 函数

    Matrix<int, 3, 3> m4;
    Matrix<int, 3, 3> m5(3);
    m5 = m4 * 2;  //This works
    m5 = 2 * m4;  //Gives an error for this
    cout << m5 << endl;

矩阵.h

#include <exception>

template <class T, int M, int N>
Matrix<T, M, N> operator*(T, const Matrix<T, M, N> &);

template <class T, int M, int N>
class Matrix
{
private:
    T mat[M][N];
    int rows = M;
    int cols = N;

public:
    // Error class
    class IllegalOperation : public std::exception
    {
    public:
        IllegalOperation(const char *msg) : _msg(msg) {}
        virtual const char *what() const throw() { return _msg.c_str(); };

    private:
        std::string _msg;
    };
    // constructor
    Matrix(int v = 0)
    {
        for (int i = 0; i < M; i++)
        {
            for (int j = 0; j < N; j++)
                mat[i][j] = v;
        }
    }

    // () overloading
    T &operator()(int i, int j)
    {
        return mat[i][j];
    }

    const T &operator()(int i, int j) const
    {
        return mat[i][j];
    }

    // [] overloading
    T *operator[](int index)
    {
        return mat[index];
    }
    const T *operator[](int index) const
    {
        return mat[index];
    }

    // << overloading
    friend std::ostream &operator<<(std::ostream &os, const Matrix<T, M, N> &L)
    {
        for (int i = 0; i < M; i++)
        {
            for (int j = 0; j < N; j++)
                os << L.mat[i][j] << " ";
            os << "\n";
        }
        return os;
    }

    template <class T1, int M1, int N1>
    Matrix<T, M, N1> operator*(Matrix<T1, M1, N1> const &other);
    template <class T1, int M1, int N1>
    const Matrix<T, M, N1> operator*(Matrix<T1, M1, N1> const &other) const;
    Matrix<T, M, N> operator+(Matrix<T, M, N> const &other);

    // scalar
    Matrix<T, M, N> operator*(T);
    friend Matrix<T, M, N> operator*<>(T scalar, const Matrix<T, M, N> &other);

    friend T min(Matrix obj)
    {
        T result = obj.mat[0][0];
        for (int i = 0; i < M; i++)
        {
            for (int j = 0; j < N; j++)
                if (result < obj.mat[i][j])
                    result = obj.mat[i][j];
        }
        return result;
    }

    long double avg() const
    {
        long double result = 0;
        for (int i = 0; i < M; i++)
        {
            for (int j = 0; j < N; j++)
                if (result < mat[i][j])
                    result = result + mat[i][j];
        }
        return result / (M * N);
    }
};

template <class T, int M, int N>
Matrix<T, M, N> Matrix<T, M, N>::operator+(Matrix const &other)
{
    if ((this->rows == other.rows) && (this->cols == other.cols))
    {
        Matrix<T, M, N> resultantMatrix;

        for (auto i = 0; i < this->rows; i++)
        {
            for (auto j = 0; j < this->cols; j++)
            {
                auto &valueFirst = this->mat[i][j];
                auto &valueSecond = other.mat[i][j];

                // if ((additionOverflow(valueFirst, valueSecond)) || (additionUnderflow(valueFirst, valueSecond)))
                //     throw std::out_of_range("Resultant value of matrix is out of range");
                // else
                resultantMatrix(i, j) = valueFirst + valueSecond;
            }
        }
        return resultantMatrix;
    }
    else
        throw IllegalOperation("Matrices cannot be added, sizes do not match");
}

template <class T, int M, int N>
template <class T1, int M1, int N1>
Matrix<T, M, N1> Matrix<T, M, N>::operator*(Matrix<T1, M1, N1> const &other)
{
    std::cout << M << " " << N1;
    if (N == M1)
    {
        Matrix<T, M, N1> resultantMatrix;

        for (auto i = 0; i < this->rows; i++)
        {
            for (auto j = 0; j < this->cols; j++)
            {
                for (auto k = 0; k < this->cols; k++)
                {
                    auto &valueFirst = this->mat[i][k];
                    auto &valueSecond = other(k, j);

                    // if ((additionOverflow(valueFirst, valueSecond)) || (additionUnderflow(valueFirst, valueSecond)))
                    //     throw std::out_of_range("Resultant value of matrix is out of range");
                    // else
                    resultantMatrix(i, j) += valueFirst * valueSecond;
                }
            }
        }
        return resultantMatrix;
    }
    else
        throw IllegalOperation("Matrices cannot be multipled, sizes not compatible");
}

template <class T, int M, int N>
template <class T1, int M1, int N1>
Matrix<T, M, N1> const Matrix<T, M, N>::operator*(Matrix<T1, M1, N1> const &other) const
{
    if (N == M1)
    {
        Matrix<T, M, N1> resultantMatrix;

        for (auto i = 0; i < this->rows; i++)
        {
            for (auto j = 0; j < this->cols; j++)
            {
                for (auto k = 0; k < this->cols; k++)
                {
                    auto &valueFirst = this->mat[i][k];
                    auto &valueSecond = other(k, j);

                    // if ((additionOverflow(valueFirst, valueSecond)) || (additionUnderflow(valueFirst, valueSecond)))
                    //     throw std::out_of_range("Resultant value of matrix is out of range");
                    // else
                    resultantMatrix(i, j) += valueFirst * valueSecond;
                }
            }
        }
        return resultantMatrix;
    }
    else
        throw IllegalOperation("Matrices cannot be multipled, sizes not compatible");
}

的功能m * 2,这有效

// scalar m * T
template <class T, int M, int N>
Matrix<T, M, N> Matrix<T, M, N>::operator*(T scalar)
{
    Matrix<T, M, N> resultantMatrix;

    for (auto i = 0; i < this->rows; i++)
    {
        for (auto j = 0; j < this->cols; j++)
        {
            auto valueFirst = this->mat[i][j];
            if (scalar == 0)
                resultantMatrix(i, j) = 0;
            // else if ((multiplicationOverflow(valueFirst, scalar)) || (multiplicationUnderflow(valueFirst, scalar)))
            //     throw std::out_of_range("Resultant value of matrix is out of range");
            else
                resultantMatrix(i, j) = this->mat[i][j] * scalar;
        }
    }
    return resultantMatrix;
}

的功能2 * m,这不起作用

template <class T, int M, int N>
Matrix<T, M, N> operator*(T scalar, const Matrix<T, M, N> &other)
{
    Matrix<T, M, N> resultantMatrix;

    for (auto i = 0; i < M; i++)
    {
        for (auto j = 0; j < N; j++)
        {
            auto valueFirst = other(i, j);
            if (scalar == 0)
                resultantMatrix(i, j) = 0;
            // else if ((multiplicationOverflow(valueFirst, scalar)) || (multiplicationUnderflow(valueFirst, scalar)))
            //     throw std::out_of_range("Resultant value of matrix is out of range");
            else
                resultantMatrix(i, j) = other(i, j) * scalar;
        }
    }
    return resultantMatrix;
}

错误

In file included from main.cpp:3:
matrix.h:4:1: error: ‘Matrix’ does not name a type
    4 | Matrix<T, M, N> operator*(T, const Matrix<T, M, N> &);
      | ^~~~~~
matrix.h: In instantiation of ‘class Matrix<int, 3, 2>’:
main.cpp:10:29:   required from here
matrix.h:76:28: error: template-id ‘operator*<>’ for ‘Matrix<int, 3, 2> operator*(int, const Matrix<int, 3, 2>&)’ does not match any template declaration
   76 |     friend Matrix<T, M, N> operator*<>(T scalar, const Matrix<T, M, N> &other);
      |                            ^~~~~~~~~~~
matrix.h:210:17: note: candidates are: ‘Matrix<T, M, N> Matrix<T, M, N>::operator*(T)’
  210 | Matrix<T, M, N> Matrix<T, M, N>::operator*(T scalar)
      |                 ^~~~~~~~~~~~~~~
matrix.h:71:28: note:                 ‘template<class T, int M, int N> template<class T1, int M1, int N1> const Matrix<T, M, N1> Matrix<T, M, N>::operator*(const Matrix<T1, M1, N1>&) const’
   71 |     const Matrix<T, M, N1> operator*(Matrix<T1, M1, N1> const &other) const;
      |                            ^~~~~~~~
matrix.h:69:22: note:                 ‘template<class T, int M, int N> template<class T1, int M1, int N1> Matrix<T, M, N1> Matrix<T, M, N>::operator*(const Matrix<T1, M1, N1>&)’
   69 |     Matrix<T, M, N1> operator*(Matrix<T1, M1, N1> const &other);
      |                      ^~~~~~~~
matrix.h: In instantiation of ‘class Matrix<int, 3, 3>’:
main.cpp:12:25:   required from here
matrix.h:76:28: error: template-id ‘operator*<>’ for ‘Matrix<int, 3, 3> operator*(int, const Matrix<int, 3, 3>&)’ does not match any template declaration
   76 |     friend Matrix<T, M, N> operator*<>(T scalar, const Matrix<T, M, N> &other);
      |                            ^~~~~~~~~~~
matrix.h:210:17: note: candidates are: ‘Matrix<T, M, N> Matrix<T, M, N>::operator*(T)’
  210 | Matrix<T, M, N> Matrix<T, M, N>::operator*(T scalar)
      |                 ^~~~~~~~~~~~~~~
matrix.h:71:28: note:                 ‘template<class T, int M, int N> template<class T1, int M1, int N1> const Matrix<T, M, N1> Matrix<T, M, N>::operator*(const Matrix<T1, M1, N1>&) const’
   71 |     const Matrix<T, M, N1> operator*(Matrix<T1, M1, N1> const &other) const;
      |                            ^~~~~~~~
matrix.h:69:22: note:                 ‘template<class T, int M, int N> template<class T1, int M1, int N1> Matrix<T, M, N1> Matrix<T, M, N>::operator*(const Matrix<T1, M1, N1>&)’
   69 |     Matrix<T, M, N1> operator*(Matrix<T1, M1, N1> const &other);
约翰

您需要在使用它之前转发声明您的类,就像这样。

template <class T, int M, int N>
class Matrix; 

template <class T, int M, int N>
Matrix<T, M, N> operator*(T, const Matrix<T, M, N> &); 

template <class T, int M, int N>
class Matrix
{
    ...
};

一个更简单的选择是删除 的声明,operator*然后在 . 的定义之后定义它Matrix像这样

template <class T, int M, int N>
class Matrix
{
    ...
};

template <class T, int M, int N>
Matrix<T, M, N> operator*(T, const Matrix<T, M, N> &)
{
    ...
}

但也许这会在您的代码中的其他地方引起问题,我看不到足够的说明。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章