A look inside "filter" function defintion

Meta jared771 at gmail.com
Tue Aug 9 21:19:21 UTC 2022


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.



More information about the Digitalmars-d-learn mailing list