Template type deduction and specialization

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed May 20 02:35:34 PDT 2015


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



More information about the Digitalmars-d-learn mailing list