Adr*_*thy 3 c++ recursion templates matrix
我有一个矩阵类,其大小由模板参数决定.
template <unsigned cRows, unsigned cCols>
class Matrix {
...
};
Run Code Online (Sandbox Code Playgroud)
我的程序使用几种大小的矩阵,通常是2x2,3x3和4x4.通过使用模板参数而不是运行时参数设置矩阵大小,编译器可以进行大量的内联和优化.
但是现在我需要一个成员函数来返回一个新的矩阵,该矩阵的行少一列,列少一列.
Matrix<cRows - 1, cCols - 1> Reduced(unsigned row, unsigned col) const { ... }
Run Code Online (Sandbox Code Playgroud)
这个想法是它将返回一个删除了指定行和列的矩阵.在实践中,这将仅使用具有至少三行和三列的矩阵来调用,在最小的位置返回2x2.
编译器没有看到下限,因此它会陷入无限递归,试图以不断减小的大小实例化模板.我尝试在函数本身中放入两条线索,这些较小的尺寸不会发生:
Matrix<cRows - 1, cCols - 1> Reduced(unsigned row, 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;
}
Run Code Online (Sandbox Code Playgroud)
对于编译器而言,static_assert或者if-statement似乎都不是一个足够强大的线索,即永远不会生成0x0矩阵.(具有讽刺意味的是,它确实抱怨if-statement具有恒定的编译时条件.)
有没有人有任何关于如何避免这种编译时无限递归的建议?
CB *_*ley 12
您需要为没有行或没有列的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>(); }
};
Run Code Online (Sandbox Code Playgroud)
您遇到的问题是尝试使用一组特定的模板参数实例化Matrix Reduced函数时,总是需要为不同的参数集(cRows - 1,cCols -1)实例化Matrix模板.这种递归必须在某处停止.如果你只处理方形矩阵,那么你可以减少专业化.
此外,如果你永远不会使用1x1矩阵,那么你可以用一个完全空的类来停止递归,这是2x2矩阵上的reduce的结果.
template<>
class Matrix< 1, 1 > {};
Run Code Online (Sandbox Code Playgroud)