c++11 - How to iterate over a std::tuple in C++ 11 -
this question has answer here:
- iterate on tuple 9 answers
i have made following tuple:
i want know how should iterate on it? there tupl_size()
, reading documentation, didn't how utilize it. have search so, questions seem around boost::tuple
.
auto = make_tuple("i good", 255, 2.1);
here attempt break down iterating on tuple component parts.
first, function represents doing sequence of operations in order. note many compilers find hard understand, despite being legal c++11 far can tell:
template<class... fs> void do_in_order( fs&&... fs ) { int unused[] = { 0, ( (void)std::forward<fs>(fs)(), 0 )... } (void)unused; // blocks warnings }
next, function takes std::tuple
, , extracts indexes required access each element. doing so, can perfect forward later on.
as side benefit, code supports std::pair
, std::array
iteration:
template<class t> constexpr std::make_index_sequence<std::tuple_size<t>::value> get_indexes( t const& ) { return {}; }
the meat , potatoes:
template<size_t... is, class tuple, class f> void for_each( std::index_sequence<is...>, tuple&& tup, f&& f ) { using std::get; do_in_order( [&]{ f( get<is>(std::forward<tuple>(tup)) ); }... ); }
and public-facing interface:
template<class tuple, class f> void for_each( tuple&& tup, f&& f ) { auto indexes = get_indexes(tup); for_each(indexes, std::forward<tuple>(tup), std::forward<f>(f) ); }
while states tuple
works on std::array
s , std::pair
s. forward r/l value category of said object down function object invokes. note if have free function get<n>
on custom type, , override get_indexes
, above for_each
work on custom type.
as noted, do_in_order
while neat isn't supported many compilers, don't lambda unexpanded parameter packs being expanded parameter packs.
we can inline do_in_order
in case
template<size_t... is, class tuple, class f> void for_each( std::index_sequence<is...>, tuple&& tup, f&& f ) { using std::get; int unused[] = { 0, ( (void)f(get<is>(std::forward<tuple>(tup)), 0 )... } (void)unused; // blocks warnings }
this doesn't cost verbosity, find less clear. shadow magic of how do_in_order
works obscured doing inline in opinion.
index_sequence
(and supporting templates) c++14 feature can written in c++11. finding such implementation on stack overflow easy. current top google hit a decent o(lg(n)) depth implementation, if read comments correctly may basis @ least 1 iteration of actual gcc make_integer_sequence
(the comments point out further compile-time improvements surrounding eliminating sizeof...
calls).
alternatively can write:
template<class f, class...args> void for_each_arg(f&&f,args&&...args){ using discard=int[]; (void)discard{0,((void)( f(std::forward<args>(args)) ),0)...}; }
and then:
template<size_t... is, class tuple, class f> void for_each( std::index_sequence<is...>, tuple&& tup, f&& f ) { using std::get; for_each_arg( std::forward<f>(f), get<is>(std::forward<tuple>(tup))... ); }
which avoids manual expand yet compiles on more compilers. pass is
via auto&&i
parameter.
in c++1z can use std::apply
for_each_arg
function object away index fiddling.
Comments
Post a Comment