加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何避免C类模板中的无限递归

发布时间:2020-12-16 10:38:38 所属栏目:百科 来源:网络整理
导读:我有一个矩阵类,其大小由模板参数决定. template unsigned cRows,unsigned cColsclass Matrix { ...}; 我的程序使用几种大小的矩阵,通常是2×2,3×3和4×4.通过使用模板参数而不是运行时参数设置矩阵大小,编译器可以进行大量的内联和优化. 但是现在我需要一
我有一个矩阵类,其大小由模板参数决定.

template <unsigned cRows,unsigned cCols>
class Matrix {
    ...
};

我的程序使用几种大小的矩阵,通常是2×2,3×3和4×4.通过使用模板参数而不是运行时参数设置矩阵大小,编译器可以进行大量的内联和优化.

但是现在我需要一个成员函数来返回一个新的矩阵,该矩阵的行少一列,列少一列.

Matrix<cRows - 1,cCols - 1> Reduced(unsigned row,unsigned col) const { ... }

这个想法是它将返回一个删除了指定行和列的矩阵.在实践中,这将仅使用具有至少三行和三列的矩阵来调用,在最小的位置返回2×2.

编译器没有看到下限,因此它会陷入无限递归,试图以不断减小的大小实例化模板.我尝试在函数本身中放入两条线索,这些较小的尺寸不会发生:

Matrix<cRows - 1,unsigned col) const {
    static_assert(cRows > 1 && cCols > 1);
    if (cRows <= 1 || cCols <= 1) throw std::domain_error();
    Matrix<cRows - 1,cCols - 1> r;
    // ... initialize r ...
    return r;
}

static_assert和if语句似乎都不是编译器的强大线索,因为永远不会生成0x0矩阵. (具有讽刺意味的是,它确实抱怨if语句具有恒定的编译时条件.)

有没有人有任何关于如何避免这种编译时无限递归的建议?

解决方法

您需要为没有行或没有列的Matrix提供专门化.

例如.

template<unsigned cRows>
class Matrix< cRows,0 >
{
    Matrix<cRows - 1,0> Reduced() { return Matrix<cRows - 1,0>(); }
};


template<unsigned cCols>
class Matrix< 0,cCols >
{
    Matrix<0,cCols - 1> Reduced() { return Matrix<0,cCols - 1>(); }
};


template<>
class Matrix< 0,0 >
{
    Matrix<0,0> Reduced() { return Matrix<0,0>(); }
};

您遇到的问题是尝试使用一组特定的模板参数实例化Matrix Reduced函数时,总是需要为不同的参数集(cRows – 1,cCols -1)实例化Matrix模板.这种递归必须在某处停止.如果你只处理方形矩阵,那么你可以减少专业化.

此外,如果你永远不会使用1×1矩阵,那么你可以用一个完全空的类来停止递归,这是2×2矩阵上的reduce的结果.

template<>
class Matrix< 1,1 > {};

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读