LoginSignup
6
2

More than 5 years have passed since last update.

if constexprと戻り値autoで型リストのfind実装

Posted at

if constexprと戻り値autoで型リストのfind実装

C++17ならわざわざテンプレートで再帰しなくても、if constexprと戻り値autoで`見た目がわかりやすく楽に実装できるんじゃないかと思ったので書く。
別にfindじゃなくても良いけどなんとなく。

結果だけならリンク先で見れます。
http://melpon.org/wandbox/permlink/d26Nr2XNmPRIk5R3

実装

find実装に必要な型

type_listtype_holder

type_list
template <typename... Args>
struct type_list;

template <typename Head, typename... Tail>
struct type_list<Head, Tail...>
{
    using head = Head;
    using tail = type_list<Tail...>;
};
type_holder
template <typename T>
struct type_holder
{
    using type = T;
};

findの実装

find
template <typename List, template <typename> typename F>
auto find()
{
    using head = typename List::head;

    if constexpr(F<head>::value)
    {
        return type_holder<head>{};
    }
    else
    {
        return find<typename List::tail, F>();
    }
}

使う

main
int main()
{
    using list = type_list<char, unsigned short, const long, double>;

    using const_type = typename decltype(find<list, std::is_const>())::type;                // const long
    using unsigned_type = typename decltype(find<list, std::is_unsigned>())::type;          // unsigned short
    using floating_type = typename decltype(find<list, std::is_floating_point>())::type;    // double
    //using error_type = typename decltype(find<list, std::is_reference>())::type;          // error
}

エラー時のことは特に考えてない。

終わりに

このような実装だとtype_holderがないと見つけたい型にデフォルトコンストラクタが必要になる(はず)。

テンプレートで再起するよりだいぶ楽になった気がする

template <typename List, template <typename> typename F>
using find_t = typename decltype(find<List, F>())::type;

こんな感じのものを用意しておけば使う方もスッキリする。

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2