Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 31, 2010 template specialization question | ||||
---|---|---|---|---|
| ||||
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 Re: template specialization question | ||||
---|---|---|---|---|
| ||||
Posted in reply to daoryn | 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 Re: template specialization question | ||||
---|---|---|---|---|
| ||||
Posted in reply to daoryn | 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 Re: template specialization question | ||||
---|---|---|---|---|
| ||||
Posted in reply to daoryn | 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 Re: template specialization question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tomek Sowiński | 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 Re: template specialization question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tomek Sowiński | � 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 Re: template specialization question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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 Re: template specialization question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Murphy | 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 Re: template specialization question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ellery Newcomer | 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 Re: template specialization question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | > 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?
|
Copyright © 1999-2021 by the D Language Foundation