| Thread overview | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
December 12, 2012 Templates array detection | ||||
|---|---|---|---|---|
| ||||
Hi,
I'm having a problem getting templates to work correctly.
I want to handle arrays differently, but when I try to compile the following example code it says it matches more than 1 template. What is the correct way to do this?
--
void main()
{
foo(1);
foo([1,1]);
}
void foo(T)(T t)
{
writeln(t);
}
void foo(T)(T[] t)
{
for(int i = 0; i < t.length; i++)
writeln(t[i]);
}
--
| ||||
December 12, 2012 Re: Templates array detection | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Cube | Cube:
> I'm having a problem getting templates to work correctly.
> I want to handle arrays differently, but when I try to compile the following example code it says it matches more than 1 template. What is the correct way to do this?
>
>
> --
> void main()
> {
> foo(1);
> foo([1,1]);
> }
>
> void foo(T)(T t)
> {
> writeln(t);
> }
>
> void foo(T)(T[] t)
> {
> for(int i = 0; i < t.length; i++)
> writeln(t[i]);
> }
> --
In general D templates refuse ambiguity. So to fix your situation you have to state that the T in your first foo overload is not an array:
import std.stdio, std.traits;
void main()
{
foo(1);
foo([1, 1]);
}
void foo(T)(T t) if (!isArray!T)
{
writeln(t);
}
void foo(T)(T[] t)
{
foreach (ti; t)
writeln(ti);
}
Bye,
bearophile
| |||
December 12, 2012 Re: Templates array detection | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Wednesday, 12 December 2012 at 12:34:34 UTC, bearophile wrote:
> Cube:
>
>> I'm having a problem getting templates to work correctly.
>> I want to handle arrays differently, but when I try to compile the following example code it says it matches more than 1 template. What is the correct way to do this?
>>
>>
>> --
>> void main()
>> {
>> foo(1);
>> foo([1,1]);
>> }
>>
>> void foo(T)(T t)
>> {
>> writeln(t);
>> }
>>
>> void foo(T)(T[] t)
>> {
>> for(int i = 0; i < t.length; i++)
>> writeln(t[i]);
>> }
>> --
>
> In general D templates refuse ambiguity. So to fix your situation you have to state that the T in your first foo overload is not an array:
>
> import std.stdio, std.traits;
>
> void main()
> {
> foo(1);
> foo([1, 1]);
> }
>
> void foo(T)(T t) if (!isArray!T)
> {
> writeln(t);
> }
>
> void foo(T)(T[] t)
> {
> foreach (ti; t)
> writeln(ti);
> }
>
>
> Bye,
> bearophile
Hi,
I eventually modified my code to:
--
void main()
{
foo(1);
foo([1,1]);
}
void foo(T)(T t)
{
bar!(T)(t);
}
void bar(T)(T t)
{
writeln(t+1);
}
void bar(T: T[])(T[] t)
{
for(int i = 0; i < t.length; i++)
writeln(t[i]);
}
--
Essentially I added a helper function that added !(T).
What, if any, is the benefit of either approach?
And a similar issue, what if I have a struct:
--
struct Data(T)
{
int elem = 3;
}
void main()
{
foo(1);
foo([1,1]);
foo(new Data!(int));
foo(new Data!(float));
}
void foo(T)(T t)
{
bar!(T)(t);
}
void bar(T)(T t)
{
writeln(t+1);
}
void bar(T: T[])(T[] t)
{
for(int i = 0; i < t.length; i++)
writeln(t[i]);
}
--
And I want to add this to the rest of the program. Where/how can I direct the Data's to separate functions?
Thanks :)
| |||
December 12, 2012 Re: Templates array detection | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Wednesday, 12 December 2012 at 12:34:34 UTC, bearophile wrote:
> Cube:
>
>> I'm having a problem getting templates to work correctly.
>> I want to handle arrays differently, but when I try to compile the following example code it says it matches more than 1 template. What is the correct way to do this?
>>
>>
>> --
>> void main()
>> {
>> foo(1);
>> foo([1,1]);
>> }
>>
>> void foo(T)(T t)
>> {
>> writeln(t);
>> }
>>
>> void foo(T)(T[] t)
>> {
>> for(int i = 0; i < t.length; i++)
>> writeln(t[i]);
>> }
>> --
>
> In general D templates refuse ambiguity. So to fix your situation you have to state that the T in your first foo overload is not an array:
>
> import std.stdio, std.traits;
>
> void main()
> {
> foo(1);
> foo([1, 1]);
> }
>
> void foo(T)(T t) if (!isArray!T)
> {
> writeln(t);
> }
>
> void foo(T)(T[] t)
> {
> foreach (ti; t)
> writeln(ti);
> }
>
>
> Bye,
> bearophile
It's a pity it doesn't see T[] as the best fit and go with it on that basis.
| |||
December 12, 2012 Re: Templates array detection | ||||
|---|---|---|---|---|
| ||||
Posted in reply to ixid | ixid:
> It's a pity it doesn't see T[] as the best fit and go with it on that basis.
It's not a pity, it's a good design. "Best fit" makes language&compiler complex, less predictable for the programmer, etc.
Bye,
bearophile
| |||
December 12, 2012 Re: Templates array detection | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Cube | Better example code for my other problem. How can I make the 3rd foo work on Datas?
--
struct Data(T)
{
T elem;
}
void main()
{
foo(1);
foo([1,1]);
auto tmp1 = new Data!(int);
tmp1.elem = 3;
foo(tmp1);
auto tmp2 = new Data!(string);
tmp2.elem = "hello";
foo(tmp2);
}
void foo(T)(T t) if(!isArray!T)
{
writeln(t + 1);
}
void foo(T)(T t) if(isArray!T)
{
for(int i = 0; i < t.length; i++)
writeln(t[i]);
}
void foo(T)(T t) if(is(T == Data)) // ?
{
if(is(T == Data!int))
writeln(t.elem + 1);
else if(is(T == Data!string))
writeln(t.elem);
}
--
| |||
December 12, 2012 Re: Templates array detection | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Cube | On 12/12/2012 06:49 AM, Cube wrote:
> Better example code for my other problem. How can I make the 3rd foo
> work on Datas?
>
> --
> struct Data(T)
> {
> T elem;
> }
Data is a struct template, not a type (until instantiated).
> void foo(T)(T t) if(is(T == Data)) // ?
This works:
void foo(T)(T t) if(is(T == Data!T))
> {
> if(is(T == Data!int))
> writeln(t.elem + 1);
> else if(is(T == Data!string))
> writeln(t.elem);
> }
> --
Ali
| |||
December 12, 2012 Re: Templates array detection | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Wednesday, 12 December 2012 at 15:21:16 UTC, Ali Çehreli wrote: > On 12/12/2012 06:49 AM, Cube wrote: > > Better example code for my other problem. How can I make the > 3rd foo > > work on Datas? > > > > -- > > struct Data(T) > > { > > T elem; > > } > > Data is a struct template, not a type (until instantiated). > > > void foo(T)(T t) if(is(T == Data)) // ? > > This works: > > void foo(T)(T t) if(is(T == Data!T)) It doesn't seem to work for me, it uses the first foo. And I can't see how it would work, actually. If T is a Data!float, then wouldn't is(T == Data!T) be equal to is(Data!float == Data!Data!float) ? > > Ali | |||
December 12, 2012 Re: Templates array detection | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Ali Çehreli:
> This works:
>
> void foo(T)(T t) if(is(T == Data!T))
Try:
void foo(T)(Data!T t) {
Bye,
bearophile
| |||
December 12, 2012 Re: Templates array detection | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Wednesday, 12 December 2012 at 14:21:22 UTC, bearophile wrote:
> ixid:
>
>> It's a pity it doesn't see T[] as the best fit and go with it on that basis.
>
> It's not a pity, it's a good design. "Best fit" makes language&compiler complex, less predictable for the programmer, etc.
>
> Bye,
> bearophile
It seems very similar to a function overload to me. Why is picking T[] in preference to T different to picking uint over ulong for an overloaded function used on a uint?
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply