While doing some testing, I came across this behavior:
template foo(T) {
void foo() {}
}
void main()
{
foo!(int).foo();
//foo!(int)(); // this works
}
Error:
testbug.d(7): Error: template testbug.foo does not match any function
template declaration. Candidates are:
testbug.d(1): testbug.foo(T)()
testbug.d(7): Error: template testbug.foo(T)() cannot deduce template
function from argument types !()(void)
This happens on 2.063 and 2.061.
From D spec: http://dlang.org/template.html
If a template has exactly one member in it, and the name of that member is
the same as the template name, that member is assumed to be referred to in
a template instantiation:
template Foo(T) {
T Foo; // declare variable Foo of type T
}
void test() {
Foo!(int) = 6; // instead of Foo!(int).Foo
}
...
I would have expected that foo!(int).foo() is equivalent to foo!(int)().
Is this no longer the case? Is there some issue here with DMD
aggressively evaluating foo!(int) to be a call because of the no-arg
function?
Actually, it does seem that way, if I change foo to accept a parameter,
and call:
foo!(int).foo(1);
I get:
testbug.d(7): Error: foo (int t) is not callable using argument types ()
testbug.d(7): Error: foo (int t) is not callable using argument types ()
(and yes, double the error).
I can't at the moment think of a reason why anyone would ever use the full
syntax, but I would expect it to be accessible, and for the compiler to
treat foo as a template first, function call second.
-Steve

This is true, but there is an implicit call going on in the function
version.
Incidentally, testing shows that foo!int.foo in your case is the int, not
the struct.
Renaming the foo member to foox, it now complains similarly (can't find
member foo, did you mean foox?).
It appears that the expanded version of eponymous templates is pretty much
disabled at this point. I'm not sure this is a bad thing, but it should
at least be documented. I'm pretty sure this used to work, but I'd have
to download an old version of DMD to figure that out :)
-Steve

I can't at the moment think of a reason why anyone would ever
use the full syntax, but I would expect it to be accessible,
and for the compiler to treat foo as a template first, function
call second.
-Steve

I do believe that the idea is that once a template is
"eponymous", then all calls are supposed to be aggressively
expanded to the internal name, and not just "can be omitted".
Once you've written the template, it is immediately "assumed" to
be the eponymous call. At that point, trying to make a fully
qualified call fails, because the template was already "expanded"
(for lack of a better word).
Leaving the possibility to choose both syntax would allow
ambiguity, which is never good: Your template is either
eponymous, or it isn't. It's not "sometimes eponymous".
From what you have shown, I'd just say 2.062 introduced a bug,
which was fixed by 2.063.
EDIT: Allow I think that there is a bug that a template becomes
eponymous when it contains a single public function that is
eponymous, regardless of other functions. IMO, that is a good
thing, but the spec state that there should be ONLY members with
the same name.
As for the "Exactly one": That's bullocks, unless you mean that
overloads define a single function. There are tons of places
where we use a template with overloaded eponymous resolution. I
think the spec is wrong on that one.