メタ関数2

if_

特殊化を使うと条件の真偽によって型の選択ができます。それをif_というメタ関数にしましょう。
boostでは

  • true/falseを直接渡す→if_c
  • メタ関数の結果としてtrue/falseのvalueを渡す→if_

となっています。

//condがtrueの時はT1を、falseの時はT2を返す
//基本形
template< bool cond, typename T1, typename T2 >
struct if_c;
//true時の特殊化
template< typename T1, typename T2 >
struct if_c< true, T1, T2 >
{
    typedef T1 type;
};
//false時の特殊化
template< typename T1, typename T2 >
struct if_c< false, T1, T2 >
{
    typedef T2 type;
};

//cond(is_系のメタ関数など)::valueがtrueの時はT1を、falseの時はT2を返す
template< typename cond, typename T1, typename T2 >
struct if_
{
    typedef typename if_c< cond::value, T1, T2 >::type type;
};

これを使ってshared_ptr_traitsを書き換えることもできますね。

template < typename T >
struct shared_ptr_traits
{
    typedef T& reference_t;
};
template<>
struct shared_ptr_traits< void >
{
    typedef void reference_t;
};
template < typename T >
struct shared_ptr_traits
{
    //Tがvoidのならvoid、void以外はT&を返す
    typedef typename if_<
        is_void< T >,
        void,
        T&
        >::type reference_t;
};

後者のほうがコンパイルに時間がかかりそうですが、どうなんでしょう?可読性とコンパイル時間のトレードオフ