How to properly use variadic templates (functions)?

Steven Schveighoffer schveiguy at gmail.com
Tue Dec 21 17:33:09 UTC 2021


On 12/21/21 4:28 AM, rempas wrote:
> On Tuesday, 21 December 2021 at 08:42:35 UTC, vit wrote:
>>
>> 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);
>>     }
>>
>> ```
> 
> Cool! That's probably what I wanted to do! It seems that when looping 
> inside a "static foreach" and taking the index, then I can compare it 
> with a value that is not calculated at compile time. This way I can also 
> check for the type of the variables and do my original plan which will 
> make the function even better! Thanks a lot for the help dude!!!

The reason your original isn't working is that indexing a list of 
differently-typed things cannot be done using a runtime index.

I'd say that an inner function + static foreach + switch is the best way 
to convert from runtime to compile-time values. And in general, I would 
say having function templates that handle each arg type are usually 
conducive to clean and easy code.

But in the case you are suggesting, as long as you don't need to iterate 
them out of order, what you can do is foreach the args tuple, and do 
something like:

```d
foreach(arg; args)
{
    writeUpToNextDelimeter(prompt); // updates prompt to point at next 
delimiter
    processArg(arg, prompt);
}
```

-Steve


More information about the Digitalmars-d-learn mailing list