Help needed to learn templates

Stanislav Blinov stanislav.blinov at gmail.com
Sat Mar 19 22:31:19 UTC 2022


On Saturday, 19 March 2022 at 13:38:42 UTC, Vinod K Chandran 
wrote:
> On Saturday, 19 March 2022 at 11:47:53 UTC, Stanislav Blinov 
> wrote:
>>
>> No.
>>
> First of all Thanks for the reply. The answer "No" is a wonder 
> to me. Because, from my point of view, `U` is coming from 
> nowhere. My understanding is, we can use any parameter of a 
> template inside the template. So in this case `U` is not in the 
> parameter list. It is suddenly appearing in that `static if`.

It is appearing not in the `static if`, but in the `is` 
expression, which I described further in the rest of my first 
reply. Sorry if that wasn't clear.

>
>> The test is not `T t == U[]`. It is `is(T t == U[], U)`.
>>
> Okay, I understand.
>
>> Actually, the lower case `t` is not needed there, you can 
>> simply write `is(T == U[], U)`.
>>
> So the `T` is not the type. It's the parameter. Right ? So a 
> template doesn't need a type. Only the parameter, right ? (I 
> think I am too dumb to ask this. Please forgive me.)

Oh don't worry, this topic is not at all obvious with the `is` 
expression having its own syntax and semantics. `T` is a type, a 
type you instantiate `rank` with. `template rank(T)` *does* 
expect a type as a parameter. The other template syntax - 
`template foo(alias T)` can take as `T` any symbol, not just a 
type.

>> Yes, and `U` then becomes `int[][]`. Which is why the template 
>> recurses down and instantiates itself with `U`, until `T` 
>> fails the test.
>>
> In order to understand this, I need to understand from where 
> the `U` comes.

It comes from you, the programmer. Like I said before, `is(T == 
U[], U)` means "is T an array of some type, the type which I (the 
programmer) would like to refer to as U?". That's all there is to 
it (well, not quite, but it should suffice for starters). You're 
simply introducing an identifier. So, when `T` is an `int[][][]`, 
naturally, `U` becomes an alias to `int[][]` (look at the 
converse - when `U` is `int[][]`, `U[]` is naturally an 
`int[][][]`).

You can think of that test as this:

```d
import std.traits : isDynamicArray;

// ...

static if (isDynamicArray!T)
{
     alias U = typeof(T.init[0]);
     // ...
}
```

...which would roughly be the same thing - you test if `T` is a 
dynamic array of some type, and then make an alias for that 
array's element type. It's just that the `is` expression allows 
you to create such alias in situ.


More information about the Digitalmars-d-learn mailing list