On Wednesday, May 20, 2015 06:31:11 Mike Parker via Digitalmars-d-learn wrote: > I don't understand why this behaves as it does. Given the > following two templates: > > ``` > void printVal(T)(T t) { > writeln(t); > } > void printVal(T : T*)(T* t) { > writeln(*t); > } > ``` > > I find that I actually have to explicitly instantiate the > template with a pointer type to get the specialization. > > ``` > void main() { > int x = 100; > printVal(x); > int* px = &x; > printVal(px); // prints the address > printVal!(int*)(px) // prints 100 > } > ``` > > Intuitively, I would expect the specialization to be deduced > without explicit instantiation. Assuming this isn't a bug (I've > been unable to turn up anything in Bugzilla), could someone in > the know explain the rationale behind this?
Well, if printVal!(int*)(px); prints 100, then that's a bug. It should print the address. In fact, it should be _impossible_ for the second overload of printVal to ever be instantiated. Think about it. What does T : T* mean? It means that T is implicitly convertible to T*. And when is a type ever implicitly convertible to a pointer to itself? int x = 100; int y = &x; isn't going to compile, so neither should that second overload ever end up being used. Use std.traits.isPointer if you want to test for whether a type is a pointer or not. I'm using a fairly recent version of dmd master, and it prints out the address for px in both cases when I compile your code. So, if it's printing out 100 for you on the second call, it would appear to be a bug that has been fixed at some point since 2.067 (or whatever version you're using) was released. - Jonathan M Davis