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
Post a Comment