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.

Reply via email to