On Tue, 08 Jun 2010 17:25:43 -0400, Larry Luther <larry.lut...@dolby.com>
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 correctly byte or ubyte depending on the call.
To do what you really want, use template constraints as Robert has
suggested. Before template constraints, the only way to do this properly
is to use a static if.
I should also mention that a planned enhancement for the compiler is to
make it so this kind of junk isn't necessary, you should just be able to
do this:
void get (ubyte[] buffer) {
}
void get (byte[] buffer) {
}
void get (T)(T[] buffer) {
}
I know this is planned, because it's in TDPL. BTW, are there any bug
reports for this?
-Steve