(注: C++0x フラグ、外部制限なしで GCC 4.6 に取り組んでいます。C++11 および/またはより最近のコンパイラで何が起こるかにも興味があります)
固定サイズの行列を操作するためのテンプレート クラスがあります。
template<size_t rows, size_t cols, class Type>
class MatrixFixed;
そのクラスでは、次の側面を持つ「シフト」操作を定義しました。
template<size_t rows, size_t cols, class Type>
template<size_t numRowsUp>
MatrixLogicalFixed<rows,cols,Type> MatrixLogicalFixed<rows,cols,Type>::shiftUp( const Type & filler ) const
{
if( (numRowsUp>=rows) )
{
return MatrixLogicalFixed<rows,cols,Type>(filler);
}
else
{
MatrixLogicalFixed<numRowsUp,cols,Type> temp(filler);
return this->getSubMatrix<rows-numRowsUp,cols>( numRowsUp, 0 )
.joinV( temp );
}
}
シフトする位置の数が行の総数よりも大きい場合、デフォルト値で満たされた行列を返すことができるという考え方です。ただし、これらの場合 ( numRowsUp >= rows
) コンパイルは内部コンパイラ エラーで終了します。最後のコード行のgimplify.c:691 の force_constant_size で.joinV( temp )
プロセス中のマトリックスのサイズ (私の推測):
- 戻り値: (行 x 列) 行列
getSubMatrix<rows-numRowsUp,cols>( numRowsUp, 0 )
: の場合numRowsUp>=rows
、これは size_t アンダーフローにより膨大な数になりますjoinV
関数は適切な戻りサイズを推測しようとしますが、これは不可能です。
これは joinV 宣言です):
template<size_t rows, size_t cols, class Type>
template<size_t rows2, size_t cols2>
MatrixLogicalFixed<rows+rows2,cols,Type> MatrixLogicalFixed<rows,cols,Type>::joinV(const MatrixLogicalFixed<rows2,cols2,Type> & B) const
if
条件はコンパイル時に定義されるため、これは問題のあるケースでは絶対に到達しないコードです。私がこれまでに試したこと:
- プリプロセッサでテンプレート パラメータを使用する #if --明らかに間違っています。
- トリックを実行できる任意の種類のプリプロセッサ マクロ MIN または MAX を探します。
値の無限の組み合わせがあるため、通常の部分的な特殊化は有効な回避策のようには見えません...私はあらゆる種類の解決策を受け入れます。クラスをコンパイルしたいだけです:D