February 01, 2010
Tomek Sowiński Wrote:

> Dnia 31-01-2010 o 21:39:21 Ali Çehreli <acehreli@yahoo.com> napisał(a):
> 
> > � wrote:
> >> Dnia 31-01-2010 o 20:59:47 Tomek Sowi�ski <just@ask.me> napisa�(a):
> >>
> >>> // specialization needed to limit matching types
> >>> void print(T:int)(T thing)
> >>  To be clear -- I did this to silence the compiler saying the call with
> >> array matches more than one function template declaration. I'm not sure
> >> whether the compiler is right -- it has a print specifically for arrays
> >> so it should be picked over plain print(T) as it's more specialized...
> >> any template expert here?
> >>   Tomek
> >
> > It works with dmd 2.040 without the :int specialization.
> 
> It's high time I upgraded, then.
> 
> > Also, for variety, i've used the 'is' expression as described here
> >
> >    http://digitalmars.com/d/2.0/expression.html#IsExpression
> >
> > for "conditional compilation" in the program below. I think specialization vs. conditional compilation differ semantically this way (no expert here! :) ):
> >
> > specialization: Use this definition for T matching U[]
> >
> > is expression: Consider this definition only for T matching U[]
> >
> > The effect should be the same in this case; but it feels like there must be a difference. :)
> >
> > import std.stdio;
> >
> > void print(T)(T thing)
> > {
> >      writeln("Calling print(T)");
> >      writeln(T.stringof);
> > }
> >
> > // T is an array of any Us.
> > void print(T, U)(T things)
> >      if (is (T == U[]))               // <-- is expression
> > {
> >      writeln("Calling print(T[])");
> >      writeln(T.stringof);
> > }
> >
> > void main()
> > {
> >      print(3);
> >      print([1,2,3]);
> > }
> >
> > Also it could be is (T : U[]) as well, which differs from is (T == U[]) as explained at the link above.
> >
> > Ali
> 
> Or even simpler:
> void print(T)(T[] things)
> 
> But that's "regular" not template overloading.
> 
> 
> Tomek

The "is" solution is simpler if one uses the "isArray!()" from std.traits. The function can then be correctly implemented but the original issue remains: is it a compiler bug or misinterpretation of the spec?

Adding an additional hidden type is just awkward when simpler solutions exist (and are advertised on the spec). Why go into the clutter of conditional compilation if simple template overloading should work?
February 01, 2010
On 02/01/2010 04:19 PM, daoryn wrote:
>
> The whole point of specialisation (and of templates in general) is to have functions that work for any type. Having to forcibly specify a type is like casting to a specific overload of a function. Why add clutter to the syntax when the language advertises automatic type inference?

I disagree. The whole point of specialization is to isolate specific cases that you want to handle differently. The point of templates (probably not in whole) is to parameterize types. The point of argument deduction is, as you put it, to have functions that work for any type.

I do agree that you shouldn't be having any problem whatsoever, but my previous example illustrated that specialization is not at fault. DMD just can't deduce what T is given the argument either because the syntax logically doesn't make sense, or because DMD is retarded.

try compiling the following:

import std.stdio;
void print(T:T[])(T[] thing){
    writeln("Calling print(T[])");
    writeln(T.stringof);
}
void main()
{
print([1,2,3]);
}

it gives me:

test.d(8): Error: template test.print(T : T[]) does not match any function template declaration
test.d(8): Error: template test.print(T : T[]) cannot deduce template function from argument types !()(int[3u])


February 02, 2010
daoryn wrote:
> According to http://digitalmars.com/d/2.0/template.html it is possible to specify template specialization so that DMD prefers them when instanciating templates, however the following code:
>
>
> ---------------------------------
> import std.stdio;
>
> void print(T)(T thing)
> {
> 	writeln("Calling print(T)");
> 	writeln(T.stringof);
> }
>
> void print(T:T[])(T[] things)

Regardless of the intent of the document, which may very well be outdated or wrong at this time; the specialization above is confusing.

If (T:T[]) is supposed to mean "array type", then the function parameter 'T[] things' above would mean "array of array". i.e. If T is T[], then the parameter is T[][]...

For that reason this is more logical to me, and I would expect it to be sufficient to express the specialization:

void print(T:T[])(T things)

But it still selects the general definition above...

I don't know... :)

Ali
February 02, 2010
On 02/01/2010 07:29 PM, Ali Çehreli wrote:
> daoryn wrote:
>  > According to http://digitalmars.com/d/2.0/template.html it is
> possible to specify template specialization so that DMD prefers them
> when instanciating templates, however the following code:
>  >
>  >
>  > ---------------------------------
>  > import std.stdio;
>  >
>  > void print(T)(T thing)
>  > {
>  > writeln("Calling print(T)");
>  > writeln(T.stringof);
>  > }
>  >
>  > void print(T:T[])(T[] things)
>
> Regardless of the intent of the document, which may very well be
> outdated or wrong at this time; the specialization above is confusing.
>

It is.

> If (T:T[]) is supposed to mean "array type", then the function parameter
> 'T[] things' above would mean "array of array". i.e. If T is T[], then
> the parameter is T[][]...

I wondered that too.

I think what happens is the type is matched to T[], and not T, and then it figures out from there what T should be, so that T[] in the function parameter is the same as the type passed in.

>
> For that reason this is more logical to me, and I would expect it to be
> sufficient to express the specialization:
>
> void print(T:T[])(T things)
>
> But it still selects the general definition above...
>
> I don't know... :)
>
> Ali

1 2
Next ›   Last »