c++11 - How to iterate over a std::tuple in C++ 11 -


this question has answer here:

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::arrays , std::pairs. 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

Popular posts from this blog

c++ - QTextObjectInterface with Qml TextEdit (QQuickTextEdit) -

javascript - angular ng-required radio button not toggling required off in firefox 33, OK in chrome -

xcode - Swift Playground - Files are not readable -