T... args!

Petar Petar
Thu Dec 9 10:34:31 UTC 2021


On Thursday, 9 December 2021 at 00:36:29 UTC, Salih Dincer wrote:
> On Wednesday, 8 December 2021 at 23:47:07 UTC, Adam Ruppe wrote:
>> On Wednesday, 8 December 2021 at 23:43:48 UTC, Salih Dincer 
>> wrote:
>>
>> I think you meant to say
>>
>> void foo(string[] args...) {}
>
> Not exactly...
>
> ```d
> alias str = immutable(char)[];
>
> void foo(str...)(str args) {
>   foreach(ref a; args) {
>     a.writeln('\t', typeof(a).stringof);
>   }
>   str s; // "Amazing! ---v";
>   s.writeln(": ", typeof(s).stringof);
> }
> ```

Unlike [value template parameters][0] (which constitute of 
existing type + identifier), all other template parameter forms 
introduce a brand new identifier in the template scope that is 
completely unrelated to whatever other types you may have outside 
in your program (including the ones implicitly imported from 
`object.d` like `string`).

The `str...` in your `foo` function introduces a [template 
sequence parameter][1] which shadows the `str` `alias` you have 
above. The `str s;` line declares a variable of the `str` type 
sequence, so it's essentially a tuple (*). See:

See:

```d
import std.stdio : writeln;

alias str = immutable(char)[];

void foo(str...)(str args) {
   foreach(ref a; args) {
     a.writeln('\t', typeof(a).stringof);
   }
   str s; // "Amazing! ---v";
   s.writeln(": ", typeof(s).stringof);
}

void main()
{
     foo(1, true, 3.5);
}
```

```
1	int
true	bool
3.5	double
0falsenan: (int, bool, double)
```

(*) Technically, you can attempt to explicitly instantiate `foo` 
with non type template arguments, but it will fail to compile, 
since:
* The `args` function parameter demands `str` to be a type (or 
type sequence)
* The `s` function local variable demands `str` to be a type (or 
type sequence)

If you can either remove `args` and `s` or filter the sequence to 
keep only the types:

```d
import std.meta : Filter;
enum bool isType(alias x) = is(x);
alias TypesOnly(args...) = Filter!(isType, args);

void foo(str...)(TypesOnly!str args)
{
     static foreach(s; str)
         pragma (msg, s);
}

void main()
{
     static immutable int a = 42;
     foo!(int, double, string)(3, 4.5, "asd");
     pragma (msg, `----`);
     foo!(a, "asd", bool, foo, int[])(true, []);
}
```

```
int
double
string
----
42
asd
bool
foo(str...)(TypesOnly!str args)
int[]
```

[0]: https://dlang.org/spec/template.html#template_value_parameter
[1]: https://dlang.org/spec/template.html#variadic-templates


More information about the Digitalmars-d-learn mailing list