我正在寫一個模板數學矩陣類來適應一些新的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