知り合いがTMPについて解説してたので我もTMPのテクニックの解説をするなり。
とりあえずサンプルコードはgistに置いといた。
ここTemplate Meta Programming(略してTMP)とはC++の機能のtemplateを利用してほげほげするほげである。Wikipediaに「コンパイラがテンプレートを使って一時的ソースコードを生成し、それを他のソースコードと結合してコンパイルする方式である。」と書いてあるがわけがわからなかったら無視していい。templateでほげほげすることは確かである。
通常TMPといえば「値に関する操作」「型に関する操作」の2種類あるが値に関する操作はconstexprでことがすむので型に関する操作の話をしていく。型に関する操作とはいかにという話だが例えばサンプルコードのexam1.cpp。
これはtorio型が渡されたらその真ん中の型を取り出してtypedefするクラスである。要するにこんな感じで型で遊んでいくわけ。もちろんただ遊ぶのではなく有意義に遊ぶ。
TMPには様々なテクニックがあるがよく知られているテクニックを2つ紹介する。
1つ目はExpression Template。式をtemplateで表すテクニックである。
例えばサンプルコードのexam2.cpp。これが要素数1万とかになってくると普通にoperator+を実装したのでは一時オブジェクトでその分メモリを消費したりするのでよろしくない。
exam2.cppのようにoperator+の返り値をadd_vectorにすることでoperator[]が呼び出されるまで計算されないようにするのである。遅延評価をするという話だ。
上では数値計算に使ったがそれ以外にも使い道はある。例えばexam3.cpp。C++にはコンパイル時ラムダ式がコア言語でサポートされてないのでそれをライブラリで対応したりできる。まぁこれでコンパイル時ラムダ式を完全にサポートするのは割とめんどくさそうなので暇な人は頑張ってください。
上のコードでは演算子オーバーロードにADLを使っている。ここらへんの解説はめんどくさいので自分で検索して下さい。なんかADLは邪悪らしいとか地雷原がいっぱいとか聞いたことあるので地雷原回避する方法誰か教えてくださいお願いします。
2つ目はType Erasure。型の情報を必要最低限まで抹消するテクニックである。例えばexam4.cpp。この他にも自作のVTableのほげほげをほげする方法はあるらしいがそれは参考リンクを参照。
これはすなわち基底クラスのポインタに派生クラスのポインタを入れれることを利用する(ここでは派生クラスのunique_ptrは基底クラスのunique_ptrにキャストしている)
ほとんど説明することもないと思う。読めば分かるという感じ。
TMPはまだまだ奥が深い、他にも色々テクニックがあるので色々調べればいいと思う。
間違ってること言ってたら誰か教えて欲しいですはい。
あとgist無理矢理使おうとしてこんな感じになってしまった。
参考ページ(Cryolite先生のはてなダイアリー)
http://d.hatena.ne.jp/Cryolite/20040506http://d.hatena.ne.jp/Cryolite/20051003PR