首页 > 解决方案 > 使用 std::common_type_t 的 C++ 矩阵类运算符和复数的实现

问题描述

我自己正在编写一个矩阵类,并且我试图使其尽可能“通用”,即我希望 amatrix<int> + matrix<double>能够 yield matrix<double>matrix<double> * matrix<int>能够 yield 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;
    }
}

标签: c++matrixtype-conversionoperator-overloadingcomplex-numbers

解决方案


您不应该将两个模板合二为一。尝试这个:

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>and you return 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<但不要将它们用于复杂矩阵。

这里的 operator> 与 std::complex 不兼容。如果我使用复杂的矩阵,我不知道如何解决它。

在模板类中有这个成员很好。只是不要将它与复杂的矩阵一起使用。但是,我建议您将其设为免费功能。那么你就完全没有这个顾虑了。


推荐阅读