C++ 矩阵模板 class 切片

C++ matrix template class slice

为了学习 C++ 模板,我正在编写一个简单的 Matrix class。到目前为止它一直运行良好,但我想添加对矩阵进行切片以提取子矩阵的功能。我正在努力弄清楚如何定义 return 矩阵的大小。我尝试了以下方法:

#include <cstdint>
#include <array>
#include <initializer_list>

template<typename T, std::size_t M, std::size_t N>
class Matrix
{
    public:
        Matrix(void): m_data{0} {}

        Matrix(const std::initializer_list<std::initializer_list<T>> m)
        {
            for(auto i = m.begin(); i != m.end(); i++)
            {
                for(auto j = i->begin(); j != i->end(); j++)
                {
                    (*this)(i - m.begin(), j - i->begin()) = *j;
                }
            }
        }

        T& operator()(const std::size_t i, const std::size_t j)
        {
            return m_data.at(i + j * N);
        }

        const T& operator()(const std::size_t i, const std::size_t j) const
        {
            return m_data.at(i + j * N);
        }

        template<std::size_t X, std::size_t Y>
        Matrix<T,X,Y> slice(const std::size_t iStart, const std::size_t iEnd, const std::size_t jStart, const std::size_t jEnd)
        {
            Matrix<T,iEnd-iStart+1,jEnd-jStart+1> result;

            for(std::size_t i = iStart; i <= iEnd; i++)
            {
                for(std::size_t j = jStart; j <= jEnd; j++)
                {
                    result(i - iStart, j - jStart) = (*this)(i,j);
                }
            }

            return result;
        }
};

int main(void)
{
    Matrix<double,3,3> m1 = {{1,2,3},{4,5,6},{7,8,9}};
    Matrix<double,2,2> m2 = m1.slice(0,1,0,1);
    return 0;
}

但我只是收到一条错误消息说 'iEnd' is not a constant expression。解决这个问题的正确方法是什么?

不能使用函数参数实例化模板。您需要将尺寸作为模板参数传递给 slice:

template<std::size_t iStart, std::size_t iEnd, std::size_t jStart, std::size_t jEnd,
         std::size_t I = iEnd-iStart+1, std::size_t J = jEnd-jStart+1>
Matrix<T,I,J> slice()
{
    Matrix<T,I,J> result;
    ///...
    return result;
}