On Friday, 31 January 2020 at 15:37:06 UTC, Steven Schveighoffer
wrote:
On 1/30/20 9:10 AM, ShadoLight wrote:
but to give you some historical perspective...
[..]
It was actually much more restrictive before -- e.g. in order
to do an eponymous template, you could have no other members in
the template.
Thanks for the historical perspective Steve. Appreciated.
When you refer to 'other members' in the eponymous template, I
notice that they are indeed allowed, but are effectively hidden
(if they have a different name from the template name) inside the
eponymous template, correct?
For example, this works fine in 'classical' template style - all
members are 'public' and accessible:
template bar(T) {
T z; //Allowed...
void b1(T x){z+=x;} //Allowed...
void b2(T x){z-=x;} //Allowed...
}
void main()
{
bar!(int).b1(4); //Works..
writeln(bar!int.z); //Works..
bar!(int).b2(5); //Works..
writeln(bar!int.z); //Works..
}
For eponymous templates, only members with the overloaded
template identifier are accessible 'from the outside'.
template foo(T) {
T z; //Allowed...
void foo(T x){f1(x);} //Allowed...
T foo(){return z;} //Allowed...
void f1(T x){z+=x;} //Allowed...
}
void main()
{
foo(3); //Works..
foo(4); //Works..
writeln(foo!int.z); //onlineapp.d(21): Error: no property z
for type int
foo!int.f1(3); //onlineapp.d(21): Error: no property f1
for type int
writeln(foo!int()); //Works..
}
So the eponymous template invocation has to use the eponymous
'trick' and only overloaded members are accessible.
Not bad and definitely an improvement , but I still find the
inconsistency jarring... IIUC this 'ambiguity' would have been
avoidable if template argument braces were not optional, right?
I do know this horse has bolted, but personally I think it D made
a mistake to make the braces on compile-/run-time arguments on
template/function invocation optional in the zero/one argument
case.
It is not even completely symmetric between compile- and
run-time: in compile time you can leave the braces off in the
case of zero and one arguments, but for run-time only for zero
arguments.
For want of the effort to type 2 braces, a fair bit of complexity
and some inconsistency has been introduced into the language. And
I remember that it actually made code harder to read when I
started out in D, not easier.
I support the dropping of the braces in the case of property
functions, but that use case is quite clear-cut and I think easy
to handle based on the @property annotation.