template specialization
    Steven Schveighoffer 
    schveiguy at yahoo.com
       
    Wed Jun  9 05:44:51 PDT 2010
    
    
  
On Tue, 08 Jun 2010 17:25:43 -0400, Larry Luther <larry.luther at 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 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
    
    
More information about the Digitalmars-d-learn
mailing list