Relax template sequence parameters, explicit template sequence arguments

Quirin Schroll qs.il.paperinik at gmail.com
Thu Feb 20 03:46:08 UTC 2025


Template sequence parameters (`Ts...`) must be the last parameter 
of a template. That also means one can only have one of them per 
template.

To facilitate passing a sequence to a sequence parameter, a new 
syntactical construct is needed. For simplicity, I’ll use `!()`. 
It would only be needed if a template with a non-terminal 
sequence parameter is explicitly instantiated.

```d
void f(Ts..., Rs...)(Ts ts, Rs rs) { }
```
```d
f(); // Ts = !(), Rs = !()
f(1,2,3); // Ts = !(int, int, int), Rs = !()
f!(!(int))(1,2,3); // Ts = !(int), Rs = !(int, int)
f!(!(int), !(int, long))(1,2,3); // Ts = !(int), Rs = !(int, long)
f!(!int, int, long)(1,2,3); // Ts = !(int), Rs = !(int, long)
// The `()` are optional if it’s a single token
// The last sequence matches individually stated arguments 
(current behavior)
```

Other use case: Make it hard to pass certain arguments
```d
void f(Ts..., size_t line = __LINE__)(Ts args) { pragma(msg, 
line); }
```
```d
f!(int, int)(1, 2); // good, Ts = !(int, int)
f!(int, int, 0)(1, 2); // error, tries Ts = !(int, int, 0), but 
`0` is not a type
f!(!(int, int), 0)(1, 2); // good (won’t happen by accident)
```

Note: `!(Args…)` would not produce an `AliasSeq!(Args…)`. It’d be 
part of the template argument list syntax:
```diff
  TemplateInstance:
     Identifier TemplateArguments

  TemplateArguments:
     ! ( )
     ! ( TemplateArgumentList )
     ! TemplateSingleArgument

  TemplateArgumentList:
     TemplateArgument
     TemplateArgument ,
     TemplateArgument , TemplateArgumentList

  TemplateArgument:
     Type
     AssignExpression
     Symbol
+   TemplateArguments
```


More information about the dip.ideas mailing list