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

Reply via email to