Bug 2372 – Template parameter types given as template parameter inhibits template instantiation + missing line number
Status
RESOLVED
Resolution
WONTFIX
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2008-09-24T03:15:00Z
Last change time
2017-06-28T09:06:08Z
Keywords
diagnostic, rejects-valid
Assigned to
nobody
Creator
simen.kjaras
Comments
Comment #0 by simen.kjaras — 2008-09-24T03:15:26Z
Passing the type of a template parameter as another template parameter causes errors when compiling. Take the following code:
////
void foo(T, T t)(mystruct!(T, t) bar)
{
}
struct mystruct(T, T t)
{
}
void main()
{
mystruct!(int, 2) baz;
foo(baz);
}
////
Compiling it yields this result:
Error: identifier 'T' is not defined
Error: T is used as a type
foo.d(12): template foo.foo(T,T t) does not match any function template declarat
ion
foo.d(12): template foo.foo(T,T t) cannot deduce template function from argument
types !()(mystruct!(int,2))
Note also that the first two messages have no line number.
Comment #1 by simen.kjaras — 2010-06-17T10:44:15Z
*** Issue 2239 has been marked as a duplicate of this issue. ***
Comment #2 by hsteoh — 2014-07-12T04:42:39Z
Still happens in git HEAD.
Comment #3 by johnnymarler — 2014-11-04T15:55:08Z
Can you confirm this code has basically the same issue or should a new bug be filed for it?
--------------------------------------
import std.stdio;
template Transform(T)
{
alias Transform = T;
}
void testTransform(T)(Transform!T t)
{
}
void testNoTransform(T)(T t)
{
}
void main(string[] args)
{
testTransform(3); // FAILS "cannot deduce function..."
testTransform!int(3);
testNoTransform(3);
testNoTransform!int(3);
}
--------------------------------------
The test(3) line fails with this error message:
main.d(15): Error: template main.testTransform cannot deduce function from argument types !()(int), candidates are:
main.d(7): main.testTransform(T)(Transform!T t)
Comment #4 by simen.kjaras — 2017-06-28T09:06:08Z
Jonathan Marler's code does indeed exhibit the same issue, and gives a small demonstration of why this will never work in the general case. For a more explicit demonstration:
void foo(T)(Bar!T value) {}
template Bar(T) {
alias Bar = string;
}
foo("test"); // What is T?
Clearly, in this case T cannot be determined. Real life examples could be significantly more complex, and even involve CTFE and string mixins. There's simply no way to make this work in the language.