Searching and Manipulation of Parameter Packs
2014 年頃に提案されていたペーパー、N4144, Searching and Manipulation of Parameter Packs をふと見かけて少し思うところがあったのでそれについてのチラ裏記事(特別新しい技術、発想ではないと思うのだが、何だかんだ同じような事をしている有名どころを見た事がないので)。
同ペーパー内でis_contained_in
というメタ関数が提案されている。これは、パラメータパックに対して線形時間をかけて指定された型がその内部に含まれるかチェックするメタ関数である。しかし実際の利用においては、この機能では乏しすぎる。実際に利用したいのは、ある型T
が含まれるかではなくあるポリシーに沿う型が含まれるかであって、ある型T
が含まれるかはあるポリシーに沿う型が含まれるかで表現できる。また、ポリシーは<type_traits>
の資産を活かして表現できる設計が好ましいように思う。
conditional
を使うと無駄なインスタンス化が発生しうるのでそれを使わない実装としている。次のように利用できる。
#include <srook/tmpl/vt/is_contained_in_like.hpp> #include <type_traits> #include <string> struct X{}; using namespace srook::tmpl::vt; typedef packer<float, int, double> type1; typedef packer<packer<X, int>, packer<std::string, int>> type2; typedef packer<packer<X, int>, packer<int, int>> type3; static_assert(is_contained_in_like<is_integral, type1>{}); static_assert(!is_contained_in_like<is_convertible, type2>{};) // == !conjunction<is_convertible<X, int>, is_convertible<std::string, int>>::value static_assert(is_contained_in_like<is_same, type3>{};) // == is_contained_in<T, packer<Ts...>>::value
packer
の内部にpacker
を持たせると、第一引数で渡されたメタ関数にそのpacker
を 1 単位として転送する。実際に多くの場面で利用するためにはこれの亜種としていくらかメタ関数を作っておくと便利だ。例えば、あるポリシーに沿う型をある型に置き換えるといった処理の場合、次のようなメタ関数があれば便利になるだろう。
これは、例えば以下のようにして利用できる。
これは与えられた算術型の内、整数型を全て浮動小数点数型にする関数の冒頭であるが、このようにして宣言する事で、型を見るだけで(は言い過ぎかもしれないが)関数そのものの動作を把握する事もできる。