У меня есть класс матрицы с размером, определяемым параметрами шаблона.
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
-статист имеет постоянное условие времени компиляции.)
Есть ли у кого-нибудь предложения о том, как избежать этой бесконечной рекурсии во время компиляции?