Thread overview
template type deduction of static 2d arrays
Oct 24, 2014
uri
Oct 24, 2014
Rikki Cattermole
Oct 24, 2014
ketmar
Oct 24, 2014
ketmar
Oct 24, 2014
uri
Oct 24, 2014
uri
Oct 25, 2014
ketmar
Oct 25, 2014
uri
Oct 25, 2014
ketmar
October 24, 2014
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
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
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
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
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
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
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
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
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.