使用std :: common_type_t的C ++矩阵类运算符和复数的实现

时间:2018-10-08 21:53:20

标签: c++ matrix type-conversion operator-overloading complex-numbers

我自己编写了一个矩阵类,并试图使其尽可能“泛型”,即,我希望matrix<int> + matrix<double>能够产生matrix<double>matrix<double> * matrix<int>能够产生matrix<double>

所以在我的operator+中,我的课堂声明是

template<typename T>
class Matrix {
public:
    ......
    template <typename TT> Matrix operator+(const Matrix<TT>&);
    ......
private:
    ......
}

定义是

template<typename T, typename TT>
Matrix<T> Matrix<TT>::operator+(const Matrix<T> &M)
{
    using C = std::common_type_t<T, TT>;
    Matrix<C> temp(_rows, _cols);
    for (size_t i = 0; i < size(); ++i)
        temp.mtx[i] = mtx[i] + M.mtx[i];
    return temp;
}

但是,编译器抱怨

  

模板参数列表必须与参数列表匹配

我不知道哪里出了问题。有人可以帮我从这里出去吗?谢谢。

至于执行复数。有些操作与std :: complex不兼容,例如max,min,operator <等。我想出的解决方案是我为复杂矩阵编写了新的矩阵类,但这很愚蠢。有没有简单的方法解决这个问题?

================================================ ======================

我的构造函数:

template <typename T>
Matrix<T>::Matrix() { allocate(0.0); }    // this is a private function allocating memory

allocate成员

template<typename T>
void Matrix<T>::allocate(T val)
{
    mtx = new T [_rows * _cols];
    if(val) {
        for (size_t i = 0; i < _rows * _cols; ++i)
            mtx[i] = val;
    }
}

1 个答案:

答案 0 :(得分:0)

您不应将两个模板合而为一。试试这个:

template<typename TT>
template<typename T>
Matrix<T> Matrix<TT>::operator+(const Matrix<T> &M)
{
    using C = std::common_type_t<T, TT>;
    Matrix<C> temp(_rows, _cols);
    for (size_t i = 0; i < size(); ++i)
        temp.mtx[i] = mtx[i] + M.mtx[i];
    return temp;
}

但是,返回类型为Matrix<T>,而您返回Matrix<C>。因此,我建议您这样写(不要忘了相应地调整声明):

template<typename TT>
template<typename T, typename C = std::common_type_t<T, TT>> // pseudocode, see below
Matrix<C> Matrix<TT>::operator+(const Matrix<T> &M) const
{
    Matrix<C> temp(...);
    ...
    return temp;
}

完整示例:

template<class T>
struct Matrix
{
    template<class S, class C = std::common_type_t<T, S>>
    Matrix<C> operator+(const Matrix<S>&) const;
};

template<class T>
template<class S, class C>
Matrix<C> Matrix<T>::operator+(const Matrix<S>&) const
{ ... }

自C ++ 14起,您可以使用auto返回类型:

template<class T>
struct Matrix
{
    template<class S>
    auto operator+(const Matrix<S>&) const
    {
        using C = std::common_type_t<T, S>; 
        Matrix<C> tmp(...);
        ...
        return tmp;
    }
};

关于第二个问题,不清楚是什么问题。请注意,除非使用模板成员函数,否则它们不会被实例化。因此,您可以使用例如operator<的成员函数,只是不要将它们用于复杂的矩阵。

  

运算符>这里与std :: complex不兼容。如果使用复杂矩阵,我不知道该如何解决。

最好将此成员包含在模板类中。只是不要将其用于复杂矩阵。但是,我建议您make it a free function。这样您就完全不用担心了。