我正在写一个模板数学矩阵类来适应一些新的C++ 11点的特性,基本宣告如下:调用模板函数递归(C++)
template <typename Type, int kNumRows, int kNumCols>
class Matrix { ... };
类有一个成员函数返回一个未成年人(后来用于计算N×N矩阵的行列式)。
Matrix<Type, kNumRows - 1, kNumCols - 1> minor(const int row, const int col) {
static_assert(kNumRows > 2, "");
static_assert(kNumCols > 2, "");
...
}
我然后创建了一个非成员函数来计算任何正方形矩阵的行列式:)
template <typename Type, int kSize>
Type determinant(const Matrix<Type, kSize, kSize>& matrix) {
switch (kSize) {
case 2:
return 0; // For now unimportant
case 3:
// Recursively call the determinant function on a minor matrix
return determinant(matrix.minor(0, 0));
}
...
}
在主(I创建一个3×3矩阵并在其上调用determinant
。 这不会编译。编译器有效地移动到案例3,创建一个次矩阵并在其上调用determinant
。 然后它再次步入case 3
,通过尝试创建1x1次要结果产生static_assert。
问题很简单:我在这里错过了什么吗?是否像递归调用模板函数简单地不允许?这是一个编译器故障(我怀疑它)?
为了完整起见,我使用了Clang ++。
只是一个小的设计评论 - 你真的不应该使用尺寸或索引“INT”;另一个需要避免的是常量传值;请参阅http://www.viva64.com/en/a/0050/和http://www.viva64.com/en/t/0030/和http://www.devx.com/tips/Tip/26546 – Matt
@Matt:感谢提醒,我查看了链接。切换到size_t/ptrdiff_t。按常值传递确实看起来有点偏离,但Herb Sutter(链接指向的人)自己说'仍然使参数在同一个函数的定义中为常量,如果它不会被修改'。当我使用模板时,声明和定义在同一个文件中,这使得剪切结点变得有点困难。 –
当然,没问题!模板的含义好点,够公平的。 – Matt