Thread overview |
---|
October 24, 2014 template type deduction of static 2d arrays | ||||
---|---|---|---|---|
| ||||
Hi All, I was wondering why in the code below f1() works but f2 template version called in the same manner does not. Is there a good reason from a language/compiler perspective? Thanks. uri --- auto f1(int[2][2] m) { return m[0][0]*m[1][1]-m[0][1]*m[1][0]; } auto f2(T)(T[2][2] m) { return m[0][0]*m[1][1]-m[0][1]*m[1][0]; } void main() { auto res = f1( [[1,2],[3,4]]); // works assert(res == -2); res = f2([[1,2],[3,4]]); // deos not work } Calling f2() as done above gives the following error: Error: cannot deduce function from argument types !()(int[][]), candidates are: f2(T)(T[2][2] m) |
October 24, 2014 Re: template type deduction of static 2d arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to uri | On 25/10/2014 11:32 a.m., uri wrote: > Hi All, > > I was wondering why in the code below f1() works but f2 template version > called in the same manner does not. Is there a good reason from a > language/compiler perspective? > > Thanks. > uri > > > --- > auto f1(int[2][2] m) > { > return m[0][0]*m[1][1]-m[0][1]*m[1][0]; > } > auto f2(T)(T[2][2] m) > { > return m[0][0]*m[1][1]-m[0][1]*m[1][0]; > } > > void main() > { > auto res = f1( [[1,2],[3,4]]); // works > assert(res == -2); > > res = f2([[1,2],[3,4]]); // deos not work > } > > Calling f2() as done above gives the following error: > > Error: cannot deduce function from argument types !()(int[][]), > candidates are: > f2(T)(T[2][2] m) res = f2(cast(int[2][2])[[1,2],[3,4]]); Should work. I believe this the old nefarious type deduction problem for literal arrays. Basically the array literals are not literally literals but instead normal arrays. |
October 24, 2014 Re: template type deduction of static 2d arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to uri Attachments: | On Fri, 24 Oct 2014 22:32:57 +0000 uri via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: D doesn't try to convert types on template argument deduction. what you really get from '[[1,2],[3,4]]' is (int[][]), not (int[2][2]). note that static arrays are not the same thing as dynamic arrays. for 'f1' compiler doing this behind the curtains: 'cast(int[2][2])[[1,2],[3,4]]'. but for 'f2' compiler can't do this, it must use the type that was given to it. so it tries template with 'int[][]' and fails. you can either change your template to `auto f2(T)(T[][] m)` (so it accepts dynamic arrays', or explicitly cast your array literal: `res = f2(cast(int[2][2])[[1,2],[3,4]]);`. |
October 24, 2014 Re: template type deduction of static 2d arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to uri Attachments: | On Fri, 24 Oct 2014 22:32:57 +0000 uri via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > Hi All, > > I was wondering why in the code below f1() works but f2 template version called in the same manner does not. Is there a good reason from a language/compiler perspective? > > Thanks. > uri > > > --- > auto f1(int[2][2] m) > { > return m[0][0]*m[1][1]-m[0][1]*m[1][0]; > } > auto f2(T)(T[2][2] m) > { > return m[0][0]*m[1][1]-m[0][1]*m[1][0]; > } > > void main() > { > auto res = f1( [[1,2],[3,4]]); // works > assert(res == -2); > > res = f2([[1,2],[3,4]]); // deos not work > } > > Calling f2() as done above gives the following error: > > Error: cannot deduce function from argument types !()(int[][]), > candidates are: > f2(T)(T[2][2] m) by the way, this will work too: int[2][2] v = [[1,2],[3,4]]; res = f2(v); 'cause 'v' has correct type, and initializing 'v' does 'magic casting'. |
October 24, 2014 Re: template type deduction of static 2d arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Friday, 24 October 2014 at 23:20:02 UTC, ketmar via Digitalmars-d-learn wrote:
> On Fri, 24 Oct 2014 22:32:57 +0000
> uri via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:
>
>> Hi All,
>>
>> I was wondering why in the code below f1() works but f2 template version called in the same manner does not. Is there a good reason from a language/compiler perspective?
>>
>> Thanks.
>> uri
>>
>>
>> ---
>> auto f1(int[2][2] m)
>> {
>> return m[0][0]*m[1][1]-m[0][1]*m[1][0];
>> }
>> auto f2(T)(T[2][2] m)
>> {
>> return m[0][0]*m[1][1]-m[0][1]*m[1][0];
>> }
>>
>> void main()
>> {
>> auto res = f1( [[1,2],[3,4]]); // works
>> assert(res == -2);
>>
>> res = f2([[1,2],[3,4]]); // deos not work
>> }
>>
>> Calling f2() as done above gives the following error:
>>
>> Error: cannot deduce function from argument types !()(int[][]), candidates are:
>> f2(T)(T[2][2] m)
> by the way, this will work too:
>
> int[2][2] v = [[1,2],[3,4]];
> res = f2(v);
>
> 'cause 'v' has correct type, and initializing 'v' does 'magic casting'.
Thanks for replying.
I think it should work because there's no ambiguity. I now have to uglify my code and make it !@safe or create a temporary.
I also noticed this when trying things out:
auto f2(T)(int[2][2] m) // Same error as above
auto f2()(int[2][2] m) // Works as per non-template function
On a related note, does the D spec guarantee the following will be rectangular in memory?
auto a = [ [1,2],[3,4] ];
Cheers,
uri
|
October 24, 2014 Re: template type deduction of static 2d arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to uri | On Friday, 24 October 2014 at 23:46:28 UTC, uri wrote:
>
> On a related note, does the D spec guarantee the following will be rectangular in memory?
>
> auto a = [ [1,2],[3,4] ];
>
>
> Cheers,
> uri
I just checked the docs and auto a = [ [1,2],[3,4] ] will be an an array of pointers. So this cannot work (unless the compiler truly is magical :)
auto a = [ [1,2],[3,4] ];
cast(int[2][2])(a);
but this should work:
enum a = [ [1,2],[3,4] ];
cast(int[2][2])(a);
(all untested)
Thanks,
uri
|
October 25, 2014 Re: template type deduction of static 2d arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to uri Attachments: | On Fri, 24 Oct 2014 23:46:27 +0000 uri via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > On a related note, does the D spec guarantee the following will be rectangular in memory? > > auto a = [ [1,2],[3,4] ]; ah, no, it's not. this is array of arrays, i.e. 'int[][]'. only static arrays are guaranteed to be placed as one block of data. this will: int[2][2] a = [ [1,2],[3,4] ]; we have a nice PR from Kenji that allows the following declarations: int[$][$] a = [ [1,2],[3,4] ]; but alas, it's not in the mainline yet. |
October 25, 2014 Re: template type deduction of static 2d arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Saturday, 25 October 2014 at 00:00:54 UTC, ketmar via Digitalmars-d-learn >
> we have a nice PR from Kenji that allows the following declarations:
>
> int[$][$] a = [ [1,2],[3,4] ];
>
> but alas, it's not in the mainline yet.
This will be cool, especially auto[$][$] also works.
thanks,
uri
|
October 25, 2014 Re: template type deduction of static 2d arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to uri Attachments: | On Sat, 25 Oct 2014 00:38:37 +0000 uri via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > On Saturday, 25 October 2014 at 00:00:54 UTC, ketmar via Digitalmars-d-learn > > > > > we have a nice PR from Kenji that allows the following declarations: > > > > int[$][$] a = [ [1,2],[3,4] ]; > > > > but alas, it's not in the mainline yet. > This will be cool, especially auto[$][$] also works. yes, it works with that PR. i don't remember why it wasn't accepted, though. i'm using it in my DMD build since day one and observed no problems at all. |
Copyright © 1999-2021 by the D Language Foundation