Template Usage with Eponymous Trick

ShadoLight ettienne.gilbert at gmail.com
Sun Feb 2 23:39:10 UTC 2020


On Sunday, 2 February 2020 at 18:30:17 UTC, Steven Schveighoffer 
wrote:

Thanks for taking the time to explain. However, when I tested my 
results does not seem to match your explanation.

>
> First, note that:
>
> struct S(T) {}
>
> is *exactly* equivalent to (in fact, you can write it this way, 
> and it works exactly the same):
>
> template S(T) { struct S {} }

Yes, agreed.

>
> So does S!int refer to the template instantiation (which is not 
> a type) or the eponymous S struct inside the template (which is 
> a type)? This was Paul's point.

I get what you are trying to say, but testing actually shows 
S!int is already a type in the eponymous case (but not in the 
classical case). If I do as in Paul's example...

template S(T) {
     struct S {T x;}
}

// Should this assertion pass or fail?
static assert(is(S!(int)));   //PASS

void main()
{
     auto a = S!(int)(3);
     writeln(typeof(a).stringof);
}

... it actually compiles and the assertion passes (and prints 
S!int as the type), so it seems the eponymous template 
instantiation already created its eponymous struct as well, no?

But I guess that in terms of 'short-hand' syntax it actually 
makes sense since it is an eponymous template and, as you/Paul 
explained previously, it should only be invoked in this way.

In contrast, for the  non-eponymous case....

template R(T) {
     struct Q {T x;}
}

// Should this assertion pass or fail?
//static assert(is(R!(int)));  //FAIL

void main()
{
     auto b = R!(int).Q(3);
     writeln(typeof(b).stringof);	
}

... now the assertion fails as expected, but the type printed is 
simply Q.

So we actually have this:

template S(T) {
     struct S {}
}

template R(T) {
     struct Q {}
}

static assert(is(S!(int)) == true);   //PASS
static assert(is(R!(int)) == false);  //PASS

I can understand (as @MoonlightSentinel's example showed), that 
optional braces can make this ambiguous and that is the current 
situation.

But, my question was if this was avoidable if braces were not 
optional. Paul's answer was that non-optional braces will not 
make...
     alias a = S!(int);
... non-ambiguous, but I still don't get that based on the above 
results.



More information about the Digitalmars-d-learn mailing list