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

Reply via email to