On Monday, 1 August 2022 at 23:35:13 UTC, pascal111 wrote:
This is the definition of "filter" function, and I think it
called itself within its definition. I'm guessing how it works?
'''D
template filter(alias predicate)
if (is(typeof(unaryFun!predicate)))
{
/**
Params:
range = An $(REF_ALTTEXT input range, isInputRange,
std,range,primitives)
of elements
Returns:
A range containing only elements `x` in `range` for
which `predicate(x)` returns `true`.
*/
auto filter(Range)(Range range) if
(isInputRange!(Unqual!Range))
{
return FilterResult!(unaryFun!predicate, Range)(range);
}
}
'''
I think this line needs explanation:
'''D
return FilterResult!(unaryFun!predicate, Range)(range);
'''
To give a vastly simplified answer, the term "eponymous template"
essentially means that if you have an item declared inside a
template that has a same name as the template:
```D
template SomeTemplate(T)
{
alias SomeTemplate = T;
}
```
It is not a compile error. Instead, when you use the template:
```D
SomeTemplate!int n;
```
The compiler rewrites your code like to:
```D
SomeTemplate!int.SomeTemplate n;
```
Because normally when you instantiate a template, you have to
refer to the declarations inside it by name:
```D
template SomeOtherTemplate(T)
{
alias SomeAlias = T;
}
//SomeOtherTemplate!int n; Error: `SomeOtherTemplate!int` is used
as a type
SomeOtherTemplate!int.SomeAlias n; //Ok
```
Except in the special case I outlined above. It's essentially a
hack that was brought over from C++. It makes using templates
more ergonomic.