C++ の std::tuple で動的にループする
たまに C++ を書かないと忘れるので…。
[コード]
#include <tuple> #include <iostream> #include <string> template<typename F, typename T, std::size_t I> void apply_impl(F f, T const& t){ f(std::get<I>(t)); } template<typename F, typename T, std::size_t ...Indices> void apply_impl(F f, T const& t, std::size_t n, std::index_sequence<Indices...>){ ((void (*[sizeof...(Indices)])(F, T const&)){apply_impl<F, T, Indices>...})[n](f, t); } template<typename F, typename ...Args> void apply(F f, std::tuple<Args...> const& t, std::size_t n){ apply_impl(f, t, n, std::index_sequence_for<Args...>()); } template<typename F, typename ...Args> void for_each(std::tuple<Args...> const& t, F f){ for(std::size_t i = 0 ; i < sizeof...(Args) ; ++i){ apply(f, t, i); } } int main(){ using namespace std::literals; auto data = std::tuple(1, 3.14, "homu"s); auto print = [](auto it){ std::cout << it << std::endl; }; apply(print, data, 0); apply(print, data, 1); apply(print, data, 2); for_each(data, [](auto it){ std::cout << it + it << std::endl; }); return 0; }
[出力]
1 3.14 homu 2 6.28 homuhomu
参考にしたコードはこのあたり。
動的に要素にはアクセスしているけど、値を返すことは出来ないので多相ラムダを渡して、それに値を渡すようにしています。
まー、実際 for_each
だけなら std::apply
とか使ったほうがよさそう。
#include <tuple> #include <iostream> #include <string> template<typename F, typename ...Args> void for_each(std::tuple<Args...> const& t, F f){ std::apply([&](auto... args) constexpr{ (f(args), ...); }, t); } int main(){ using namespace std::literals; auto data = std::tuple(1, 3.14, "homu"s); for_each(data, [](auto it){ std::cout << it + it << std::endl; }); return 0; } /* 2 6.28 homuhomu */