C++14 で Boost.Fusion の invoke と make_fused 書いてみた
C++14 で Boost.Fusion の invoke と make_fused を簡単に書いてみました。
[ソース]
#include <tuple> #include <array> #include <utility> #include <iostream> template< typename F, typename Seq, std::size_t ...Indexes > constexpr auto invoke_impl( F func, Seq const& seq, std::index_sequence<Indexes...> ){ return func(std::get<Indexes>(seq)...); } template<typename F, typename Seq> constexpr auto invoke(F func, Seq const& seq){ return invoke_impl(func, seq, std::make_index_sequence<std::tuple_size<Seq>{}>{}); } template<typename F> auto make_fused(F func){ return [=](auto seq){ return invoke(func, seq); }; } struct disp{ void operator()() const{} template<typename T, typename ...Args> void operator()(T t, Args... args) const{ std::cout << t << std::endl; (*this)(args...); } }; int main(){ invoke(disp{}, std::make_tuple(1, 2, 3)); auto f = make_fused(disp{}); f(std::make_tuple(1, 2, 3)); f(std::make_tuple(1, "homu", 3.14)); return 0; }
[出力]
1 2 3 1 2 3 1 homu 3.14
http://melpon.org/wandbox/permlink/7EHCtHou4ZWMiyg2
invoke は以前 C++11 で constexpr 版を書いた事があるんですが、make_fused を書いたのは初めてかな。
多相ラムダと関数の戻り値型の推論の組み合わせが便利そすぎる…。
これであとは constexpr だと最強なんだけど。
あと C++14 だと 標準ライブラリに std::make_index_sequence にあるので、invoke の実装も楽ですね。
余談ですが手元の clang の調子が悪かったので wandbox 使ってみたんですけど便利。