On Tue, 08 Jun 2010 17:25:43 -0400, Larry Luther <[email protected]>
wrote:
This code:
import std.stdio;
class A {
void get (T:ubyte)(T[] buffer) {
writefln( "get (T:ubyte)(T[] buffer)\n");
}
void get (T:byte)(T[] buffer) {
writefln( "get (T:byte)(T[] buffer)\n");
}
void get (T)(T[] buffer) {
writefln( "get (T)(T[] buffer)\n");
}
}
void main () {
A foo = new A;
ubyte[100] ub;
byte[100] bb;
int[100] ib;
foo.get( ub);
foo.get( bb);
foo.get( ib);
}
Generates:
get (T:ubyte)(T[] buffer)
get (T:ubyte)(T[] buffer)
get (T)(T[] buffer)
Note: If "get(T:byte)" preceeded "get(T:ubyte)" then "get(T:byte)"
would be
called in both cases.
Q: Is this the way it's supposed to be?
Thanks, Larry
Here is your mistake:
T:U as defined by the spec means any T that implicitly casts to U, not a T
that exactly equals U. Since ubyte and byte implicitly cast to eachother,
the first template matches, no matter the order.
But there is a more subtle mistake in what you are doing.
The mistake is here:
void get (T:ubyte)(T[] buffer) {
writefln( "get (T:ubyte)(T[] buffer)\n");
}
You are assuming that because of this printout, the same instantiation is
used. BUT... The instantiations are different!
You should try this instead:
void get (T:ubyte)(T[] buffer) {
writefln( "get (T:ubyte)(T[] buffer), T == %s\n", T.stringof);
}
What you will find is the first template is used, but the template
parameter T is byte.
To do what you really want, use template constraints as Don has
suggested. Before template constraints, the only way to do this properly
is to use a static if.
-Steve