tuple展開も容易になった時代
スライドを作っていて色々と文書を漁って、今頃気付いた。
apply() call a function with arguments from a tuple (V3)
いつの間にこんな文書が...二年以上も前じゃないか。
#include<experimental/tuple> #include<string> #include<functional> inline void f(int,float,std::string&&){} int main() { struct X{void f(int,float,std::string&&){}}; std::experimental::apply(f,std::make_tuple(42,42.0f,"hoge")); std::experimental::apply([](int,float,std::string&&){},std::make_tuple(42,42.0f,"hoge")); std::experimental::apply(std::mem_fn(&X::f),std::make_tuple(X(),42,42.0f,"hoge")); }
しかも確認すれば、関数オブジェクトも渡せるじゃないか。素晴らしい。
まさか標準化されていたとは、思ってもいなかった。
それに気づかず、left arrow operator(<-)を引数付きのメンバ関数にも対応してみた - Rokiのチラ裏のエントリでは、applyを自作してしまった。車輪の再発明以外の何物でもない。
std::applyを用いて上記エントリの内容を実装すると、以下のようになる。
#include<map> #include<experimental/tuple> template<class _Tp> struct larrow{ larrow(_Tp* a_):a(a_){} _Tp* a; }; template<class _Tp,class R> constexpr R operator<(R (R::* f)(),larrow<_Tp> it) { return (it.a->*f)(); } template<class _Tp,class R> constexpr R operator<(R (R::* f)()const,larrow<_Tp> it) { return (it.a->*f)(); } template<class _Tp,class R,class... FuncArgs,class... Tuple_Args> R operator<(std::pair<R (_Tp::*)(FuncArgs...),std::tuple<Tuple_Args...>> pr,larrow<_Tp> it) { return std::experimental::apply(pr.first,std::tuple_cat(std::make_tuple(it.a),pr.second)); } template<class _Tp> larrow<_Tp> operator-(_Tp& a){return larrow<_Tp>(&a);}
非常に短く済む。C++は、本当に便利な時代になったものだ。