gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 19:42:50 25 4
gpt4 key购买 nike

我有一个矩阵类,其大小由模板参数决定。

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

我的程序使用几种尺寸的矩阵,通常为 2x2、3x3 和 4x4。通过使用模板参数而不是运行时参数设置矩阵大小,允许编译器进行大量内联和优化。

但现在我需要一个成员函数来返回一个少了一行和一列的新矩阵。

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

这个想法是,它将返回一个删除了指定行和列的矩阵。在实践中,这只会用至少具有三行和三列的矩阵调用,最小返回 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;
}

无论是 static_assert 还是 if 语句似乎都不足以向编译器提供永远不会生成 0x0 矩阵的线索。 (具有讽刺意味的是,它确实提示 if 语句具有恒定的编译时条件。)

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

最佳答案

您需要为没有行或列的矩阵提供特化。

例如

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 模板。这种递归必须在某处停止。如果您只处理方矩阵,那么您可以使用较少的特化。

此外,如果您永远不会使用 1x1 矩阵,即 2x2 矩阵上的 reduce 结果,则可以使用一个完全空的类来停止递归。

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

关于c++ - 如何避免 C++ 类模板中的无限递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1252117/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com