How to properly use variadic templates (functions)?

vit vit at vit.vit
Tue Dec 21 08:42:35 UTC 2021


On Tuesday, 21 December 2021 at 08:26:17 UTC, rempas wrote:
> On Tuesday, 21 December 2021 at 08:11:39 UTC, Anonymouse wrote:
>>
>> I'm not certain I understand, but won't `foreach (i, a; args) 
>> { /* ... */ }` in his example do that?
>>
>> As in, if you necessarily must index `args` instead of using a 
>> foreach variable,
>>
>> ```d
>> import core.stdc.stdio : putc, stdout;
>>
>> void print(T...)(string prompt, T args)
>> {
>>     foreach (i, a; args)
>>     {
>>         alias A = typeof(args[i]);
>>
>>         static if (is(A : string))
>>         {
>>             for (int j = 0; j < args[i].length; j++)
>>             {
>>                 putc(args[i][j], stdout);
>>             }
>>         }
>>         else
>>         {
>>             // handle your other types
>>             print("", A.stringof);
>>         }
>>     }
>> }
>>
>> void main()
>> {
>>     print("Prompt (ignored)", "Hello", " world!\n", 123);
>> }
>> ```
>
> No it will not. I will try to explain it the best way I can. 
> When I say I want to index args, I mean that I want to index 
> and choose which argument to use rather than use them 
> continuously one after another inside a `foreach`. For example 
> check the following call:
>
> `print("Hello %s!%c", "world", '\n');`
>
> In that case I want to first print print from "H" up to (but 
> not include) "%s". Then I want to print the first argument. 
> After that, I want to print the '!' character and then I want 
> to print the second argument. So I need a way to keep track 
> which argument was the last one I printed and manually choose 
> which argument to use. So `foreach` will not do in that case 
> because I don't want to continuously use the arguments one 
> after another. Is is more clear now? "writef" exists in phobos 
> so I'm pretty sure that there is a way to do that.

You can use switch + static foreach:

```d
import std.stdio;

     //this print args in reverse order:
     void print(T...)(string prompt, T args)
     {
         void print_arg(size_t index){
             switch(index){
                 static foreach(i, a; args){
                 	case i:
                         // handle your other types
                         write(a);
                     	return;	
                 }
                 default:
                 	assert(0, "no impl");
             }
         }

         write(prompt);
         size_t len = args.length;
         while(len --> 0)
             print_arg(len);
     }

     void main(){
         print("Prompt (ignored): ", "Hello", " world!\n", 123);
     }

```


More information about the Digitalmars-d-learn mailing list