Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 08, 2010 template specialization | ||||
---|---|---|---|---|
| ||||
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 |
June 08, 2010 Re: template specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Larry Luther | Larry Luther <larry.luther@dolby.com> wrote: > get (T:ubyte)(T[] buffer) > > get (T:ubyte)(T[] buffer) > > get (T)(T[] buffer) > > Q: Is this the way it's supposed to be? Looks very much correct, yes. Is there a problem? -- Simen |
June 08, 2010 Re: template specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Larry Luther | On 08/06/10 22:25, Larry Luther wrote:
> Q: Is this the way it's supposed to be?
Yes, byte implicitly casts to ubyte so it's accepted. Try switching the templates round, they will both be byte. The way around this is to add template constraints to the templates:
void get(T:ubyte)(T[] buffer) if( is( T == ubyte ) ) { }
void get(T:byte)(T[] buffer) if( is( T == byte ) ) { }
etc.
Hope this helps,
Robert
|
June 08, 2010 Re: template specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert Clipsham | On 06/08/2010 05:01 PM, Robert Clipsham wrote:
> On 08/06/10 22:25, Larry Luther wrote:
>> Q: Is this the way it's supposed to be?
>
> Yes, byte implicitly casts to ubyte so it's accepted. Try switching the
> templates round, they will both be byte. The way around this is to add
> template constraints to the templates:
>
> void get(T:ubyte)(T[] buffer) if( is( T == ubyte ) ) { }
> void get(T:byte)(T[] buffer) if( is( T == byte ) ) { }
>
> etc.
>
> Hope this helps,
>
> Robert
bit odd though, since byte[] isn't implicitly convertible to ubyte[].
no wait! yes it is!
void get(T:ubyte[])(T t){}
..
get(new byte[](1));
no wait! no it isn't!
ubyte[] u = new byte[](1);
and is it just me, or does the following silently cast away immutability?
get("hi mom!");
|
June 08, 2010 Re: template specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Larry Luther | Thanks guys. Simen asked: "Is there a problem?". Well, I kind of expected a "ubyte" buffer to be matched with a "get(T:ubyte)". I thought methods were searched for the "best" match. Larry |
June 09, 2010 Re: template specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Larry Luther | Larry Luther wrote:
> Thanks guys.
>
> Simen asked: "Is there a problem?".
>
> Well, I kind of expected a "ubyte" buffer to be matched with a "get(T:ubyte)".
> I thought methods were searched for the "best" match.
No, C++ does it that way, and it gets horrendously complicated.
In D, it has to match exactly.
|
June 09, 2010 Re: template specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Larry Luther | On Tue, 08 Jun 2010 17:25:43 -0400, Larry Luther <larry.luther@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 |
June 09, 2010 Re: template specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer:
> I know this is planned, because it's in TDPL. BTW, are there any bug reports for this?
Please write one, overloading of functions with templates is an important and basic thing.
Bye,
bearophile
|
June 10, 2010 Re: template specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > Please write one, overloading of functions with templates is an important and basic thing. http://d.puremagic.com/issues/show_bug.cgi?id=3941 |
June 10, 2010 Re: template specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Larry Luther | Thanks everyone. |
Copyright © 1999-2021 by the D Language Foundation