On Tuesday, 12 March 2019 at 16:20:11 UTC, H. S. Teoh wrote:
On Tue, Mar 12, 2019 at 03:26:05PM +0000, Victor Porton via Digitalmars-d-learn wrote: [...]
On Tuesday, 12 March 2019 at 09:05:36 UTC, Nicholas Wilson wrote:
[...]
> template FieldInfo(T) {
>     template FieldInfo(Nullable!(T) default_)
>     {
>         enum FieldInfo = 0;
>     }
> }
> > seems to work, but I can't seem to instantiate one of it.

Why you use the same name "FieldInfo" for both the template and its subtemplate? Does it make some sense?

This is a D idiom called the "eponymous template". Whenever the template contains a member of the same name as the template, it's an eponymous template, and you can refer directly to the member by the template name, rather than using templateName.memberName.

For example, a template function is usually written like this:

        ReturnType myFunc(TemplateArgs...)(RuntimeArgs args...)
        {
                ... // implementation here
        }

This is actually shorthand for the eponymous template:

        template myFunc(TemplateArgs...)
        {
                ReturnType myFunc(RuntimeArgs args...)
                {
                        ... // implementation here
                }
        }

Similarly, when you write:

        enum isInputRange(T) = hasMember!(T, empty) && ...

that's actually shorthand for:

        template isInputRange(T)
        {
                enum isInputRange = hasMember!(T, empty) && ...
        }

The eponymonus template idiom allows you to use a single name to refer to both the template and the member. Without this idiom, you'd have to use the very verbose notation:

        static if (isInputRange!T.isInputRange) ...

or

        auto retval = myFunc!(A, B, C).myFunc(1, 2, 3);

I know what is eponymous template. But how it behaves when the eponymous member inside itself is also a template? How to instantiate it? (provide please an example how to instantiate)

Reply via email to