第6章 演習問題 6-0 最小の型を見つけるメタ関数

読んでる本.
C++テンプレートメタプログラミングの6章練習問題0問目.
何故か異常に手間取ったので書いておく.
問題は

copyと手作りのインサータを使い, 型の列の中から最小の型を見つけるメタ関数smallestを作れ.

BOOST_STATIC_ASSERT( (boost::is_same >::type,char >::value) );
これが済んだら, この問題を解くのにこれが良い方法かどうか考えよ. また, その理由を述べよ.

こんな感じ.

で, 出来た物.

using boost::mpl::_1;
using boost::mpl::_2;

struct none_max {};	// 最大の型として扱う型

template< typename T0, typename T1 >
struct smallest_op
	: public boost::mpl::if_<
		    boost::mpl::less< boost::mpl::sizeof_<T0>
		 	                , boost::mpl::sizeof_<T1>
			>
		  , T0	//
		  , T1	// 小さい方を採用
	>
{ };

template< typename T0 >
struct smallest_op<none_max, T0>        // 片方がnone(最初というか最後?に呼ばれる時)
	: public boost::mpl::identity<T0>   // 必ず有効な方を返す
{ };

template< typename T0, typename T1 >    // inserterの作り方分かんないので流用
struct smallest_inserter                // public継承おいしいです(^q^)
	: boost::mpl::inserter< none_max, smallest_op<T0, T1> >
{ };

template< typename Seq >
struct smallest
	: public boost::mpl::copy<    // 要件通りcopy使用
	      Seq
		// べっ,べつにあんたのために手作りしたんじゃ(ry
		, smallest_inserter<_1, _2>	
	>
{ };

むぅ…. どうみてもnone_maxがダサイ気がする.
mplに使うべき'なんでもない'型って有るのかしら? naとかvoid_とかnoneとか?

で, これが良い方法かというと….
良くない. なぜなら変な型を特殊化したりして特別扱いする必要があるので,
コードが長くなったり読みにくくなるため.
mpl::min_elementに渡す述語でがんばればどうにかなるんじゃないかという期待もある.


と思って調べたらなんとそのまんまBoostのマニュアルに答えが載っていたw

// http://www.boost.org/doc/libs/1_42_0/libs/mpl/doc/refmanual/min-element.html
typedef vector<bool,char[50],long,double> types;
typedef min_element<
      transform_view< types,sizeof_<_1> >
    >::type iter;
BOOST_MPL_ASSERT(( is_same< deref<iter::base>::type, bool> ));

素晴らしいですね.
max_elementの説明だけど, むしろviewの::base型の使い方だと思う.
ものすごく納得した.


本の感想は読み終わってから書くと思うけど, 説明が丁寧だし凄く面白いのでお勧め!

C++テンプレートメタプログラミング (Programmer’s SELECTION)

C++テンプレートメタプログラミング (Programmer’s SELECTION)