C++テンプレートメタプログラミング

RPGツクールNScripter等のツールを用いない場合、ゲーム開発にはC/C++C#等のプログラミング言語を用いることが多いと思います。
その中でも、C++には黒魔術的な要素があると言われています。
「テンプレート」というのがその黒魔術へ踏み出すための第一歩です(この記事はあくまでテンプレートの紹介程度です。詳しい説明等はないのでご了承を)。


C++を学んでいくと、「テンプレート」というものを学ぶ機会があるかもしれません。
例えば、引数として3つの値を渡し、そのうち大きいものを返す関数maxは次のようになります(効率や書きかたにはあまり突っ込まないでください)。

int max( int a , int b , int c )
{
  if( a > b ) return a > c ? a : c;
  else return b > c ? b : c;
}

これはint型を対象とした関数です。さて、double型に対してこのような関数が欲しくなった場合はどうしますか?

double max( double a , double b , double c )
{
  if( a > b ) return a > c ? a : c;
  else return b > c ? b : c;
}

このような関数を追加することで対処することが出来ます。さて、さらに他の型に対して欲しくなった場合は・・・?
そのような場合、関数を逐一追加していたらどうしようもありません。そこで出てくるのがテンプレートです。

template <class T> T max( T a , T b , T c )
{
  if( a > b ) return a > c ? a : c;
  else return b > c ? b : c;
}

templateというのは、テンプレートを使うよー、というのをコンパイラに伝えるものです。
Tというのは、汎用データ型というものであり、コンパイル時、コンパイラがいい感じで当てはまる型を検出し、置き換えてくれます。
例えば、

max( 1.0 , 2.0 , -0.5 );  // → Tはdoubleになる
int a = 20 , b = 10 , c = 40;
max( a , b , c );  // → Tはintになる

といったようなパターンがあります。


テンプレートの概要はこんなところです。便利ですよね。何故これが黒魔術になるのでしょうか?
黒魔術、つまりC++テンプレートメタプログラミングの「Hello, World」にあたる以下のコードを見てみましょう。
階乗を求めるプログラムで、「コンパイル時に階乗値を求める」処理をします。実行時には階乗計算をしません。

template <int N>
struct Factorial 
{
  enum { value = N * Factorial<N - 1>::value };
}; 
template <>
struct Factorial<0> 
{
  enum { value = 1 };
};
 
// Factorial<4>::value == 24
// Factorial<0>::value == 1
void foo()
{
  int x = Factorial<4>::value; // == 24
  int y = Factorial<0>::value; // == 1
}

早速訳が分かりませんね。このコードを見て、「すごい!面白い!」と思えたのなら、あなたには黒魔術師の素質があります(ちなみにこのコードはWikipediaの「テンプレートメタプログラミング」に載っています)。
このコードについて詳しく説明はしません。そして、「このコードが何の役に立つの?」と思われる人もいるかもしれません。
まぁ、これが役に立つことはそうそうないでしょうね。「Hell, World」と表示するプログラムに意味がないのと同じです。


以上で、テンプレートメタプログラミングのちょっとした入り口紹介みたいなものを終わります。
テンプレートメタプログラミングをうまく使えば、効率よくC++プログラムを組むことが出来ます。
C++の標準ライブラリのSTLにもふんだんにテンプレートは使われています(std::vectorやstd::listなどを使ったことがある人はいると思います。これもテンプレートを利用したクラスです)。
さらに強力なテンプレートライブラリとして、boostというライブラリがあります。
何より、合う人にはとても面白い内容です。


しかし、あまりに複雑なメタプログラミングをすると、解読が困難になってしまいます。
また、C++コンパイラはテンプレートの展開に時間がかかります(最近はCPUの性能が上がっているので、そこまででもなくなってきてはいますが)。
非常に面白く、役立つ内容ではあるのですがあんまり組み込みまくると大変なことになるかもしれません。


興味を持った人は、テンプレートメタプログラミングについて勉強してみるといいのではないでしょうか。
こんな記事を書きましたが、自分もあまり詳しくないので勉強する必要があります・・・。
C++テンプレートメタプログラミングについての書籍はAmazonでいくつかあるので、探してみるといいでしょう。
テンプレートを学んで楽しいC++ライフ!