3

マトリックスとそれらのマトリックスに対する操作を含むライブラリを作成することにより、テンプレートのスキルを向上させようとしています (私はほとんど知りません)。基本的に、行列を非常に強く型付けし (コンパイル時にデータ型とサイズがわかる)、転置行列の型を自動的に推定できるようにしたいと考えています。

template< typename TDataType, size_t rows, size_t cols > class MyMatrix

行列は入れ子にするTDataTypeことができるので、整数型にすることもできますが、MyMatrix<...>単独で行うこともできます。これにより、転置行列のデータ型が元の行列のデータ型と必ずしも同じになるとは限りません。たとえば、 Transpose( MyMatrix< MyMatrix< char, 2, 3 >, 4, 6 > ) ==> MyMatrix< MyMatrix< char, 3, 2 >, 6, 4 >(外部行列のデータ型が変更された)

転置型推定の私の最初の試みは次のとおりです。

template< typename TDataType >
struct Transpose
  {
  typedef TDataType type;
  };

template<>
struct Transpose< MyMatrix<TDataType, rows, cols> >
  {
  typedef MyMatrix<typename Transpose<TDataType>::type, cols, rows> type;
  };

Transpose-template を MyMatrix (TDataType 不明および同様のエラー) で特殊化できないように見えるため、これを行う方法が見つかりませんでした。

私が思いついた唯一のコンパイル可能なソリューションは次のとおりです(まだ機能するかどうかさえわかりません):

template< typename TMatrixType, typename TDataType, size_t rows, size_t cols >
struct Transpose
  {
  typedef TMatrixType type;
  };

template< typename TDataType, size_t rows, size_t cols >
struct Transpose< MyMatrix<TDataType, rows, cols>, TDataType, rows, cols >
  {
  typedef MyMatrix< typename Transpose<TDataType,TDataType,rows,cols>::type, cols, rows > type;
  };

私は物事を複雑にしすぎていると思います。私が望むものを達成するためのより簡単な解決策はありますか?


私の質問への回答への回答 (私はアカウントなしで質問を投稿したので、通常の方法で物事を行うのに十分な担当者がいません)。もう本当にありがとう!

@Bo Persson @Will A : これを汎用行列ライブラリとして使用するつもりはありません。特定の (事前にわかっている) サイズの行列に対して操作を実行し、このアプローチを使用してどこに到達できるかを確認したいと考えています。これにより、行列のメモリ レイアウトを最適化し (たとえば、行ベクトルを 32 バイト境界に揃える)、その他のファンキーなことを実行できるようになります。これを行うことで何度も自分の足を撃つことを期待していますが、ここで得ようとしている主なことは経験であり、何が機能し、何が機能しないかを見つけます (そして、何が難しいか、何がそうでないか) 't)。

@Bo Perrson : 最初のバージョンがコンパイルされない理由はわかっていますが、2 回目の試行で動作するより単純なバージョンがあるかどうか疑問に思っていました。主な問題は、MyMatrix がクラス テンプレート自体であり、そのテンプレート引数をどうにかして Transpose-struct に取得する必要があることです。

@VJo:うまくいかないと思います。T が MyMatrix<..> 自体である場合、転置行列はTranspose<T> T 自体ではなく、データ型として持つ必要があります。すべての基本型 (char、int、double...) については、もちろんこれは正しく、より簡単です。

4

4 に答える 4

3

はい、あなたは複雑です。

次のような宣言がある場合:

template< typename TDataType, size_t rows, size_t cols > class MyMatrix

次に、転置関数は次のようになります。

template< typename T, size_t rows, size_t cols >
MyMatrix< T, cols, rows > Transpose( const MyMatrix< T, rows, cols > & m )
{
  MyMatrix< T, cols, rows > res;
  // implementation
  return res;
}
于 2011-06-05T17:42:37.100 に答える
0

任意の深さの再帰(行列の行列の行列...)を許可するために、このように記述します。

template<typename T, unsigned rows, unsigned cols>
struct MyMatrix
{
  typedef T value_type;
  T stuff[rows][cols];  // or whatever                                      
};

// For basic types, transpose is identity.                                  
template<typename T>
struct Transpose {
  typedef T result_type;
  result_type operator()(const T & in) {
    return in;
  }
};

// For more complex types, specialize and invoke recursively.
template<typename T, unsigned rows, unsigned cols>
struct Transpose<MyMatrix<T, rows, cols> > {
  typedef MyMatrix<Transpose<T>, cols, rows> result_type;
  result_type operator()(const MyMatrix<T, rows, cols> & in) {
    Transpose<T> transposer;
    // (invoke transposer on each element of in and build result)           
  }
};

ここで、Transposeはファンクターです。インスタンスを作成しますが、関数として呼び出します。追加のクレジットとして、 typedefを無料で継承しunary_functionて取得することができます...result_type

于 2011-06-05T20:06:26.330 に答える
0

行/列をテンプレート定義の一部にすることで何が得られますか?

私の個人的な感想は、これが物事を複雑にしすぎているということです。必ずテンプレートにデータ型を含めてください。ただし、ディメンションを含めるのは間違っているようです。

于 2011-06-05T17:32:53.050 に答える
0

特殊化が別の型であり、基本テンプレートのテンプレート パラメーターが認識されていないため、最初の試行は失敗します。

言語によると 2 番目のバージョンは正しいですが、Will A が言うように、新しい型を作成するために行と列のすべての組み合わせが本当に必要ですか?

于 2011-06-05T17:42:59.120 に答える