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.

Reply via email to