プロジェクトには、静的配列として実装された行列などをカプセル化するクラスがいくつかあります。例:
struct StaticContainer
{
static const short e[2][4];
};
/// Initialize components of member-array (with external linkage).
const short StaticContainer::e[2][4] = {
{ -1, 0, 0, 1 },
{ 0, -1, 1, 0 }
};
StaticContainer :: eの列から2番目のインデックス(この場合は1〜4)に逆マッピングを提供するメタ関数を実装したいと思います。理想的には、次のようなものです。
template< typename TContainer, short TeX, short TeY >
struct VectorToIndex
{
enum { value = ??? };
};
最後に、私は合格したいと思います(これが可能であれば):
BOOST_STATIC_ASSERT( 0 == VectorToIndex< StaticContainer, -1, 0 >::value );
これは可能ですか?'e'行列を再帰的に検索する最初の試みは失敗しました。これは、(コンパイル時に)取得しようとするたびに(GCC)次のようになるためです。
error: ‘StaticContainer::e’ cannot appear in a constant-expression
マトリックスの値がコンパイル時に利用できないことを理解しますか?
コメントをいただければ幸いです。マトリックスの初期化/保存方法は自由に変更できます(したがって、コンパイル時の登録メカニズムについて考えていました)。唯一の制約は、コンパイル時にこの逆マッピングを取得することです。
明確化:
e-matrixの各列は、空間方向(この場合は2D)を表します。列は明確であることが保証されています。
メタ関数から次の結果が得られると思います。
VectorToIndex< StaticContainer, -1, 0 > --> '0' at compile-time VectorToIndex< StaticContainer, 0,-1 > --> '1' at compile-time VectorToIndex< StaticContainer, 0, 1 > --> '2' at compile-time VectorToIndex< StaticContainer, 1, 0 > --> '3' at compile-time
このテンプレートが無効な数値の組み合わせ(つまり、マトリックスの列ではない)でインスタンス化された場合、コンパイルエラーが発生します。
- 私が現在持っている解決策は、必要なテンプレートインスタンス化を使用してファイルを手動で書き込む単純なプログラムです。これは要件を満たします(結果は正しく、無効なベクトルの場合、対応するテンプレートインスタンスが欠落しているため、コンパイル時エラーが発生します)。ただし、コードベースには「StaticContainer」に似たクラスがたくさんあるので(それらの多くはより大きな行列を持っています)、このプロセスは数千行のコードを生成します:(。