+ 1

how to unpack parameters in variadic templates

----

14th Apr 2021, 8:26 PM
return 0;
return 0; - avatar
28 Answers
+ 2
By using a fold expression, you can compute the result of using a binary operator over all arguments of the pack. For template < typename... Args > auto foo( Args... args ) {} "args" represents the unexpanded pack or the first variadic argument, while ... represents the arguments to be expanded. The expression "args" appears in is then expanded for all arguments in the pack. The most important thing to know is in which way the expressions ( ... op args ) ( args op ... ) ( init op ... op args ) ( args op ... op init ) are evaluated for an operator op and an initial value init; the corresponding table can be found in the link I shared earlier. If the parameter pack is empty, the expression is usually ill-formed, except for the operators &&, || and ,. By using the sizeof...() operator, you can check the size of the parameter pack at compile time. I wrote some examples of possible use cases for direct visualization: https://code.sololearn.com/cruo0rNL68bq/?ref=app
16th Apr 2021, 1:50 PM
Shadow
Shadow - avatar
+ 1
In many contexts, you can use a fold expression that is automatically expanded by the compiler: https://en.cppreference.com/w/cpp/language/fold But it really depends on what you are trying to achieve in the first place.
14th Apr 2021, 9:58 PM
Shadow
Shadow - avatar
+ 1
Roughly yes, but maybe "args" is not exactly the current element in the sense of the first argument, but more of a placeholder that every argument in the pack is substituted into when the pack is expanded. For example, we could go ahead and write a print_double() function on top of the print() function from earlier: template < typename... Args > auto print_double( const Args&... args ) { print( args + args... ); } If you call it in a fashion like this print_double ( 7.5, std: :string( "Hello" ), std::complex< float >( 4, 2 ) ); the function call would be expanded to: print( 7.5 + 7.5, std::string( "Hello" ) + std::string( "Hello" ), std::complex< float >( 4, 2 ) + std::complex< float >( 4, 2 ) ); As you can see, each argument of print_double() is substituted into both occurences of "args" upon expansion, and therefore everything is print twice correctly. That's at least how I like to think of it.
17th Apr 2021, 7:36 AM
Shadow
Shadow - avatar
+ 1
You can't use ... on its own. It basically tells the compiler to take the expression the unexpanded pack appears in, substitute every pack argument into it, and concatenate the resulting expressions via the given binary operator. In foo4(), Types is used as an argument to std::is_same_v<> on the left side, while ... appears on the right side of &&, so it's not alone or anything. In the first code you posted, the size of the parameter pack doesn't decrease, so you never reach the base case and end up in an infinite recursive loop. The second code has no random calculations, it works exactly as expected. This is how it is executed: First call: a = 2, args = ( 3, 7 ) -> print a = 2 call print( 3 + 3, 7 + 7 ) Second call: a = 3 + 3 = 6, args = ( 7 + 7 = 14 ) -> print a = 6 call print( 14 + 14 ) Third call: a = 14 + 14 = 28, args = () -> print a = 28 call print() Fourth call: Base case, recursion stops
17th Apr 2021, 10:45 AM
Shadow
Shadow - avatar
+ 1
foo4() is going to return true if the decayed types of all arguments match (not their values). Since the parameter pack is passed by value, all types will decay, e.g. string literals decay to const char*, functions decay to function pointers, and so on.
17th Apr 2021, 3:57 PM
Shadow
Shadow - avatar
0
recursive method is getting annoying and i cant do everything with it
14th Apr 2021, 8:27 PM
return 0;
return 0; - avatar
0
its confusing
15th Apr 2021, 7:32 AM
return 0;
return 0; - avatar
0
can u explain them
15th Apr 2021, 7:32 AM
return 0;
return 0; - avatar
0
also i dont understand the three dots
15th Apr 2021, 10:28 AM
return 0;
return 0; - avatar
0
Google explanations are confusing
15th Apr 2021, 10:29 AM
return 0;
return 0; - avatar
0
unary folds are my problem
15th Apr 2021, 10:33 AM
return 0;
return 0; - avatar
0
on sample 3 does forwarding pass all arguments?
16th Apr 2021, 3:37 PM
return 0;
return 0; - avatar
0
Sure, otherwise the first static assertion in main() would fail.
16th Apr 2021, 3:48 PM
Shadow
Shadow - avatar
0
this is magical
16th Apr 2021, 4:03 PM
return 0;
return 0; - avatar
0
so arg is the current argument and ... is the others unpacked arguments?
16th Apr 2021, 4:14 PM
return 0;
return 0; - avatar
0
in ur code i saw ... is used alone in foo4 function
17th Apr 2021, 7:57 AM
return 0;
return 0; - avatar
0
what does it mean
17th Apr 2021, 7:57 AM
return 0;
return 0; - avatar
0
run the code
17th Apr 2021, 8:13 AM
return 0;
return 0; - avatar
17th Apr 2021, 8:13 AM
return 0;
return 0; - avatar
0
it has no end
17th Apr 2021, 8:13 AM
return 0;
return 0; - avatar