This is the first of a pair of implicit-instantiation-of-function issues I'm going to open. I don't know whether I should list them as bugs or feature requests. I'm going to open them as bugs, and they can be changed if appropriate.
I stumbled across this problem when I tried to build a CurryTail template (curry the *last* argument from a delegate). In the code below, CurryTailAlt will perform implicit template instantiation, but I don't like it because one delegate argument (the tail argument) shows up in both the P and T template parameters. It seems to me that DMD could deduce the template parameters in my preferred version (CurryTail):
CODE
===========
void delegate(U) CurryTail(A,U...)(void delegate(U,A) dg,A arg)
{
return null;
}
void delegate(T[0..$-1]) CurryTailAlt(P,T...)(void delegate(T) dg,P arg)
{
return null;
}
struct FooStruct
{
void foo(uint i,char c) {}
}
void bar() {
auto temp = new FooStruct;
auto dg1 = CurryTail !(char,uint)(&temp.foo, 'c'); // this works
auto dg2 = CurryTailAlt (&temp.foo, 'c'); // this works
auto dg3 = CurryTail (&temp.foo, 'c'); // this doesn't
}
=============
DMD OUTPUT
=============
implicit_instantiation1.d(20): template implicit_instantiation1.CurryTail(A,U...) does not match any template declaration
implicit_instantiation1.d(20): template implicit_instantiation1.CurryTail(A,U...) cannot deduce template function from argument types (void delegate((uint), char),char)
[russ@russ dmd_bugs]$ dmd -c implicit_instantiation1.d
implicit_instantiation1.d(20): template implicit_instantiation1.CurryTail(A,U...) does not match any template declaration
implicit_instantiation1.d(20): template implicit_instantiation1.CurryTail(A,U...) cannot deduce template function from argument types (void delegate((uint), char),char)
Comment #1 by clugdbug — 2012-09-26T01:23:56Z
Reduced test case.
------
void bug1390a(A,U)(void delegate(U,A) dg, A arg)
{}
void bug1390(A,U...)(void delegate(U,A) dg, A arg)
{}
struct FooStruct {
void foo(uint i,char c) {}
}
void bar1390() {
auto temp = new FooStruct;
bug1390a!(char,uint)(&temp.foo, 'c');
bug1390a (&temp.foo, 'c');
bug1390!(char,uint)(&temp.foo, 'c');
bug1390 (&temp.foo, 'c');
}
----
The '1390a' cases work, but on D1, the second '1390' fails. On D2 *both* of the '1390' instantiations fail.
Comment #2 by razvan.nitu1305 — 2019-08-08T13:11:04Z
This is not a valid bug report. Variadic template parameters are expanded only if there are no other trailing parameters. If you rewrite the code in the second comment to:
void bug1390a(A,U)(void delegate(U,A) dg, A arg)
{}
void bug1390(A,U...)(void delegate(A, U) dg, A arg) // A was swapped with U in
// the delegate definition
{}
struct FooStruct {
void foo(uint i,char c) {}
}
void bar1390() {
auto temp = new FooStruct;
bug1390a!(char,uint)(&temp.foo, 'c');
bug1390a (&temp.foo, 'c');
bug1390!(uint, char)(&temp.foo, 'c'); // uint was swapped with char
bug1390 (&temp.foo, 'c');
}
Then the code compiles.
Closing as WONTFIX.