■
まあようするに、データ形式に依存しないコーディングのこと。
私の場合、整数型のベクトル場と実数型のベクトル場を使うので、int 型と double 型を扱うためのテンプレートを作っています。
これでコード量が大体半分になります。
また、メンバ関数を int 型と double 型でインスタンス化しているので、分割コンパイルもできます。
まあでも、ジェネリックプログラミングよりも重要なことは、このクラスが多次元のベクトル場を表現できるくらいの抽象性をもっていること。
これひとつで、多次元グレースケール画像(n次元 →輝度の1次元)、カラー画像(縦横の2次元→RGBの3次元)、多次元ベクトル場(n次元→n次元)、行列(2次元→1次元)、n階テンソル(n次元→1次元)を表現できる。3次元オプチカルなんちゃらはもちろん、尺度なんちゃらなども実は表現できたりする。
実際には3次元ベクトル場まで使えればいいので、宣言はこんな感じ
const unsigned N=3; templateclass VF{ unsinged dimension_of_domain; // 定義域の次元 unsigned dimension_of_range; // 値域の次元 unsigned size[N]; // 各軸(次元)の定義域の大きさ std::valarray data[N]; public: VF(); VF(unsgined dimension_of_range_, unsigned size0, unsinged size1=1, unsigned size2=1); // 点(x,y,z) でのベクトルの i 番目要素の値。 i < dimension_of_range であることに注意 // 行列として使うなら、vf(0,m,n) で m 行 n 列の値にアクセスできる。まあ当然データ構造上 0 行 0 列から始まることに注意 T& VF(unsinged i,unsigned x, unsgined y=0, unsgined z=0){ return data[i][z*size[0]*size[1] +y*size[0] +x]} };
データ部分を vector または valarray で表現することにより、面倒なメモリ管理から開放されるわけです。デストラクタはいりませんし、
代入も簡単にできます。また、かなりシンプルな実装なのでわかりやすい宣言ができます。
VFmat_i(1,3,3); // 整数型 3 x 3 行列 VF mat_f(1,5,10); // 実数型 5 x 10 行列
また、コンパイル時にベクトル場の次元やサイズを決めなくてもいいことも便利です。データを読み込む必要がある場合、配列を作る場合などに対応可能。
VFimg[5]; // 5 枚の画像 for (int i=0; i<5; ++i) img[i].read(file[i]); // file[i] から読み込み
最後に重要な点として速度が上げられますが、速度はインライン展開などの最適化コンパイルに依存するかたちとなります。インライン展開すれば実のところ valarray や vector を使っているだけにすぎないので、これらの最適化性能にかかってくるわけです。