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