なぜかはてなに移行してから全く書くことが無くなってしまったんだが,このまま放っとくとネット上にゴミを増やすことになりそうなので,無理矢理なんか書いてみる.

slashdotの日記の方でがんばって作っていたInt<>とかIF<>とかfold<>とかは,当然boostにも有るわけで….
再発明が行き詰まってきたので本家を勉強中.*1

とりあえず基礎から.

これまで何となく書いていたメタ関数だけど,

インスタンシエートのタイミングを理解しておかないと,

仮にコンパイルが通っても大変なことになる予感.*2

要点は,ネストした型を使用すると,
そのテンプレートはインスタンシエートされるので,
条件分岐するときはなるべくネストした型に言及しないこと.

あんまり考えて無いバージョン

template< typename T >
struct TestMetaF {
    typedef typename if_<
        is_pointer<T>,
        typename T::type,              // int*::typeなんて型は無いのでError
        typename add_pointer<T>::type
    >::type type; // ここで適用される前に,既にそれぞれの型がインスタンシエートされてしまっている
};
// ネストしたtype型を持っていない型を渡すと,
// is_pointer<T>の真偽に関わらずコンパイルエラー
cout << typeid( TestMetaF<int*>::type ).name() << endl;

ちょっとがんばったバージョン

template< typename T >
struct TestMetaFunc {
	typedef typename if_<
		is_pointer<T>
		, T
		, add_pointer<T>    // まだ評価されてない(thunk?)
	>::type pointer_if;         // ここでは'T' orelse 'add_pointer<T>'型

	typedef typename pointer_if::type type; // ここで関数適用
};
// ネストしたtype型を持っていなくても,
// ポインタで無ければOK
cout << typeid( TestMetaFunc<int>::type ).name() << endl;

しかし色がひどいなw
デフォルトのハズなのに.

*1:今までどこから得た知識で書いていたのか謎

*2:バイナリサイズ的な意味で?