c++ - What's va_arg() in C++11 variadic template? -


this question has answer here:

i've read articles new c++11 feature didn't understand stuff (i'm new c++). how access specific argument can using va_arg stdarg.h in c?

template <typename ... args> void f(args ... args) {     for(size_t = 0; < sizeof ...(args); i++)     {         // obviously, args...[i] didn't work...     } } 

the problem type var = args[c];, write type? each i has different type, won't able use for loop this.

generally, normal approach use recursion.

void f() { } //end loop  template<class firsttype, typename...args>  void f(firsttype&& first, args&&...rest) {       //do loop body     loop_body(std::forward<firsttype>(first)...)     //do next "iteration"     f(std::forward<args>(rest)...); } 

there's way without recursion, it's bit more advanced:

template<typename...args>  void f(args&&...args) {       typedef int[] for_each;     for_each{((void)(   loop_body(std::forward<args>(args))  ),0)...,0}; } 

and finally, if want access 1 index:

//note "i" must compile time constant auto var = std::get<i>(std::tie(std::forward<args>(args)...)); 


typedef int[] code strange, , i'll lay out here.
we'd call function loop_body(std::forward<args>(args))...; unfortunately, parameter packs can expanded in contexts, , that's not 1 of them. easiest , obvious solution pass results of calls function nothing: do_nothing(loop_body(std::forward<args>(args))...), unfortunately, fails void return types, because can't instantiate void pass do_nothing. worse, call each of functions in wrong order. 1 way "convert" void expression else arcane trick comma operator, (func(), 0) executaes func , "returns" 0.
worse, reasons admittedly don't understand, f(vs)...,0; nor (f(vs),0)...,0; valid contexts expanding parameter packs. however, type array[] = {vs...} valid context. have way combine context expressions return values: int array[] = {(f(vs),0)...}; , works! mostly!
if parameter pack has 0 types (yes, that's valid. never forget it.), results in compiler error. have add 1 additional 0 on end there @ least 1 element: int array[] = {(f(vs),0)..., 0};. also, compilers warn array unused variable. 1 way bypass warning make type temporary. int = (expr); local, (int)(expr) creates unnamed temporary. want (int []){(f(vs),0)..., 0};. reasons can't recall, (int[]) hidden behind typedef. final detail, since classes can overload comma operator, it's safest cast functions void: int array[] = {((void)(f(vs)),0)..., 0};

unrelated, i've contemplated macro in past, hides ugly details little more. feel there's downside i'm overlooking or else more common.

#define foreach_variadic(expr) (int[]){((void)(expr),0)...,0}      template<typename...args>  void f(args&&...args) {       foreach_variadic(loop_body(std::forward<args>(args))); } 

Comments

Popular posts from this blog

Why can rails not find a route created by a helper? -

javascript - jquery or ashx not working -

opencv - DataType<cv::detail::deriv_type>::depth what is it used for -