2008-09-19

TR1のrefについて

Boostには、refとcrefがあるが、TR1にもある。しかし、TR1の方が、より進化した実装である。というのも、boostのrefでは、以下のようなことができない。

FuncObj fn ;
std::for_each( v.begin(), v.end(), ref(fn) ) ;

なぜこれができないかというと、Boostの実装では、reference_wrapperが、単に参照を包むだけのクラスだからだ。TR1では、関数オブジェクトの場合、単項か二項として呼ぶことができる。問題は、一体どうやって、関数オブジェクトであるのか判断するのかということだ。

渡された型が、関数や関数ポインタである場合は、簡単なメタプログラムで判断できる。メンバ関数ポインタであっても同様だ。unary_functionやbinary_functionを継承していてもよい。ここまではいいとして、result_typeというネストされた型名があればよいという変態的な仕様となっている。このネストされた型名を判断するメタプログラムというのが、何とも変態的だ。

ネストされた型名を持っているかどうかを判断するメタ関数を生成するマクロの実装例が、Boostにある。<boost/mpl/has_xxx.hpp>というのがそれで、BOOST_MPL_HAS_XXX_TRAIT_DEFを使えばよい。

追記:
ドラフト規格では、Variadic Templatesを使って、任意の引数に対応できるようになっている。

No comments: