Jump to page: 1 2
Thread overview
template specialization question
Jan 31, 2010
daoryn
Jan 31, 2010
Daniel Murphy
Feb 01, 2010
daoryn
Jan 31, 2010
Ellery Newcomer
Feb 01, 2010
daoryn
Feb 01, 2010
Ellery Newcomer
Jan 31, 2010
Tomek Sowiński
Jan 31, 2010
Tomek Sowiński
Jan 31, 2010
Ali Çehreli
Jan 31, 2010
Tomek Sowiński
Feb 01, 2010
daoryn
Feb 01, 2010
daoryn
Feb 02, 2010
Ali Çehreli
Feb 02, 2010
Ellery Newcomer
January 31, 2010
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)
{
	writeln("Calling print(T[])");
	writeln(T.stringof);
}

void main()
{
	print(3);
	print([1,2,3]);
}

-----------------------------------------

will output:

Calling print(T)
int
Calling print(T)
int[3u]

I expected it to output "calling print(T[])" on the second "print". Would this be a bug or did I misunderstand the template specialization?

January 31, 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)
> {
> 	writeln("Calling print(T[])");
> 	writeln(T.stringof);
> }
> 
> void main()
> {
> 	print(3);
> 	print([1,2,3]);
> }
> 
> -----------------------------------------
> 
> will output:
> 
> Calling print(T)
> int
> Calling print(T)
> int[3u]
> 
> I expected it to output "calling print(T[])" on the second "print". Would this be a bug or did I misunderstand the template specialization?
> 

It looks like the type of the array literal is a static array, not a dynamic one.
Static arrays can be matched with the following specification:
void print(T : U[N], U, size_t N)(T things)
Or you could use the slice operator to transform the static array into a dynamic one.
eg print([1,2,3][]);

January 31, 2010
I haven't gotten around to templates yet, so I don't grok them quite as well as I'd like, but it looks like DMD is having trouble deducing T from the parameter given.

print([1,2,3]) fails to match the specialized template, even when the general template is removed.

If you force the template parameter, it does what you would expect:


	print!(int)(3);
	print!(int[3])([1,2,3]);


Calling print(T)
int
Calling print(T[])
int

Can't say whether this belongs in bugzilla or not. It might.

On 01/31/2010 12:49 PM, daoryn wrote:

>
> I expected it to output "calling print(T[])" on the second "print". Would this be a bug or did I misunderstand the template specialization?
>

January 31, 2010
Dnia 31-01-2010 o 19:49:44 daoryn <manse@fots.po> napisał(a):

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

I'd say it should be more like:

// specialization needed to limit matching types
void print(T:int)(T thing)
{
	writeln("Calling print(T)");
	writeln(T.stringof);
}

// T is an array of any Us.
void print(T:U[], U)(T things)
{
	writeln("Calling print(T[])");
	writeln(T.stringof);
}


Tomek
January 31, 2010
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
January 31, 2010
� 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.

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
January 31, 2010
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
February 01, 2010
Daniel Murphy 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)
> > {
> > 	writeln("Calling print(T[])");
> > 	writeln(T.stringof);
> > }
> > 
> > void main()
> > {
> > 	print(3);
> > 	print([1,2,3]);
> > }
> > 
> > -----------------------------------------
> > 
> > will output:
> > 
> > Calling print(T)
> > int
> > Calling print(T)
> > int[3u]
> > 
> > I expected it to output "calling print(T[])" on the second "print". Would this be a bug or did I misunderstand the template specialization?
> > 
> 
> It looks like the type of the array literal is a static array, not a dynamic one.
> Static arrays can be matched with the following specification:
> void print(T : U[N], U, size_t N)(T things)
> Or you could use the slice operator to transform the static array into a dynamic one.
> eg print([1,2,3][]);
> 

Sadly, your solution doesnt apply. The used template is still the wrong one.

Code:

void print(T)(T thing)
{
	writeln("Calling print(T)");
	writeln(T.stringof);
}

void print(T:T[])(T[] things)
{
	writeln("Calling print(T[])");
	writeln(T.stringof);
}

void main()
{
	print(3);
	print([1,2,3][]);
}


---------------
output:

Calling print(T)
int
Calling print(T)
int[]


NOTE: DMD2.040 used.
February 01, 2010
Ellery Newcomer Wrote:

> I haven't gotten around to templates yet, so I don't grok them quite as well as I'd like, but it looks like DMD is having trouble deducing T from the parameter given.
> 
> print([1,2,3]) fails to match the specialized template, even when the general template is removed.
> 
> If you force the template parameter, it does what you would expect:
> 
> 
> 	print!(int)(3);
> 	print!(int[3])([1,2,3]);
> 
> 
> Calling print(T)
> int
> Calling print(T[])
> int
> 
> Can't say whether this belongs in bugzilla or not. It might.
> 
> On 01/31/2010 12:49 PM, daoryn wrote:
> 
> >
> > I expected it to output "calling print(T[])" on the second "print". Would this be a bug or did I misunderstand the template specialization?
> >
> 

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?
February 01, 2010
> It works with dmd 2.040 without the :int specialization.

No it doesnt. Did you use specific compiler flags? Also check that you are using the source I posted and not the modified versions presented which served only to circumvent compiler warnings and not answer the original question: is it a compiler bug or misinterpreted template specialization?
« First   ‹ Prev
1 2