条件定数式による型の選択

ある定数式が真のときと偽のときで、型定義を変更したいと思ったことはないでしょうか? 例えば、ある値が 0x7f より大きいときと小さいときで、char 型か unsigned char 型かを変えたい場合などです。

条件式が前処理式であれば、#if 指令を使って条件付きコンパイルすることが可能です。しかし、条件式に sizeof 演算子が含まれていたり、メタ関数が含まれている場合には、#if 指令ではどうすることもできません。

そんなときには、条件式に応じて返す型が変わるメタ関数を使用するのが定石です。こうしたメタ関数は、自分で作っても知れています。しかし、Boost C++ Libraries に含まれるのであれば、それを使った方がよいでしょう。

この類のメタ関数は、type_traits か mpl 辺りにあるのではないかと探してみたのですが、どうも見つかりません。しかたなく、いろいろと条件を変えて grep 検索をしていると、見つけました! それは、detail の下にこっそりあったのです。

それでは、早速使い方を見てみましょう。

#include <boost/detail/select_type.hpp>
typedef boost::detail::if_true<sizeof(int)==4>
    ::then<int, long>::type int32_type;

どのようにインデントするのがよいのか若干迷いますが、if_true の後の <...> に条件定数式を指定し、それが真であれば、then の後の <...> で指定した最初の型が、偽であれば後の型が選ばれます。

なお、この if_true を他のテンプレートの中で使うときは、

if_true<is_const<T>::value>::template then<T1, T2>::type

のように、then の直前に template を付ける必要があります。

よく考えると...

MPL の if_ や if_c で解決しますね。MPL はバージョン 1.33.x 以降ですし、1.32.x 以前のものを使う用もないので...
(Cygwin の都合で 1.33.1 を使う用事はまだあります)

このエントリーを含むはてなブックマーク