私は、テンプレートパラメータによって決定されるサイズの行列クラスを持っています。C++クラステンプレートで無限再帰を避ける方法
template <unsigned cRows, unsigned cCols>
class Matrix {
...
};
私のプログラムは、いくつかのサイズの行列、通常の2x2、3x3の、および4x4のを使用しています。ランタイムパラメータではなくテンプレートパラメータで行列サイズを設定することにより、コンパイラは多くのインライン化と最適化を実行できます。
今、私は、1つ少ない行と1つ少ない列を持つ新しい行列を返すメンバ関数が必要です。
Matrix<cRows - 1, cCols - 1> Reduced(unsigned row, unsigned col) const { ... }
考えられるのは、指定された行と列が削除された行列が返されるということです。実際には、少なくとも3行3列の行列を持ち、最小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
-statementは、0x0の行列が生成されることはありませんコンパイラに十分に強い手がかりのようです:私はこれらの小さいサイズが発生することができないという機能自体に2つの手がかりを入れてみました。 (皮肉なことに、それはコンパイル時の条件が一定のif
の文章について文句を言う)
このコンパイル時の無限再帰を避ける方法はありますか?
彼は2x2を最も小さく言った、私はまだこれが最高だと思う。おそらく 'const int MinimumRows'、' const int MinimumColumns'を追加して調整可能にしてください。 – GManNickG
ありがとう、それはトリックでした。私はそれをさらに進化させ、非還元機能を「非還元」にして、専門化を分離しやすくしました。 –