Thread overview | |||||
---|---|---|---|---|---|
|
January 31, 2020 Cannot implicitly convert expression [[0, -1, 2], [4, 11, 2]] of type int[][] to const(int[2])[] | ||||
---|---|---|---|---|
| ||||
https://wiki.dlang.org/Dense_multidimensional_arrays#Static_arrays describes a way to create static arrays: int[3][3] matrix = [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]; However my complains that I can't implicitly create static arrays from dynamic arrays. private T[R1][C2] loopMul(ulong R1, ulong C1, ulong R2, ulong C2, T)( auto ref T[R1][C1] matrixA, auto ref T[R1][C2] matrixB) if (C1 == R2) { T[R1][C2] result; for (ulong r = 0; r < R1; ++r) { for (ulong c = 0; c < C2; ++c) { T toAdd = 0; for (ulong n = 0; n < C1; ++n) { toAdd += matrixA[r][n] + matrixB[c][n]; } result[r][c] = toAdd; } } } void main() { import std; scope (success) std.writeln("loopMul -- ok"); // assert([[0, -1, 2], [4, 11, 2]].loopMul!(2, 3, 3, 2, int)([[3, -1], [1, 2], [6, 1]]) == [ // [11, 0], [35, 20] // ]); const int[2][3] matA = [[0, -1, 2], [4, 11, 2]]; const int[3][2] matB = [[3, -1], [1, 2], [6, 1]]; const int[2][2] matC = [[11, 0], [35, 20]]; assert(matA.loopMul(matB) == matC); } /// I would share the D online editor link but `shorten` button doesn't do anything onlineapp.d(24): Error: cannot implicitly convert expression [[0, -1, 2], [4, 11, 2]] of type int[][] to const(int[2])[] onlineapp.d(25): Error: cannot implicitly convert expression [[3, -1], [1, 2], [6, 1]] of type int[][] to const(int[3])[] onlineapp.d(27): Error: template onlineapp.loopMul cannot deduce function from argument types !()(const(int[2][3]), const(int[3][2])), candidates are: onlineapp.d(1): loopMul(ulong R1, ulong C1, ulong R2, ulong C2, T)(auto ref T[R1][C1] matrixA, auto ref T[R1][C2] matrixB) What's causing this? |
January 31, 2020 Re: Cannot implicitly convert expression [[0, -1, 2], [4, 11, 2]] of type int[][] to const(int[2])[] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adnan | On Friday, 31 January 2020 at 12:37:43 UTC, Adnan wrote:
> What's causing this?
You mixed up the array lengths:
const int[3][2] matA = [[0, -1, 2], [4, 11, 2]];
const int[2][3] matB = [[3, -1], [1, 2], [6, 1]];
matA is an SA containing <2> elements of type int[3].
matB is an SA containing <3> elements of type int[2].
|
January 31, 2020 Re: Cannot implicitly convert expression [[0, -1, 2], [4, 11, 2]] of type int[][] to const(int[2])[] | ||||
---|---|---|---|---|
| ||||
Posted in reply to MoonlightSentinel | On Friday, January 31, 2020 5:43:44 AM MST MoonlightSentinel via Digitalmars-d-learn wrote:
> On Friday, 31 January 2020 at 12:37:43 UTC, Adnan wrote:
> > What's causing this?
>
> You mixed up the array lengths:
>
> const int[3][2] matA = [[0, -1, 2], [4, 11, 2]];
> const int[2][3] matB = [[3, -1], [1, 2], [6, 1]];
>
> matA is an SA containing <2> elements of type int[3].
> matB is an SA containing <3> elements of type int[2].
Specifically, the dimensions are read outwards from the variable name, so on the left-hand side, that means that they go right-to-left, whereas on the right-hand side, they go left-to-right. This is consistent with how it works with types in C/C++ except that there, they put the dimensions for static arrays on the right-hand side of the variable name, meaning that while you have to read stuff like pointer types from left-to-right in C/C++, you don't have to do that with static arrays. Ultimately, what D is doing is consistent but confusing.
e.g. For C/C++
int** foo; // A pointer to a pointer to an int
int foo[5][2]; // A 5 dimensional array of two dimensional arrays of int
foo[4][1] = 7;
and for D:
int** foo; // A pointer to a pointer to an int
int[2][5] foo; // A 5 dimensional array of two dimensional arrays of int
foo[4][1] = 7;
For C/C++, you often don't realize how the rules work until you have to read function pointers, because they put the static array lengths no the right-hand side, and they actually allow you to put stuff like const in multiple places instead of only in the place where it would be right right-to-left. e.g. if the rule were followed strictly,
const int i = 0;
wouldn't be legal in C/C++. Rather, it would have to be
int const i = 0;
In reality, both work, but people end up using the first one. So, ultimately, it adds to the confusion when dealing with more complex tyypes. D doesn't have that problem, but since it used parens with type qualifiers, it forces const to go on the left, making it less consistent. e.g.
const int i = 0;
or
const(int) i = 0;
So, neither C/C++ nor D is entirely consistent, but the basic rule is that types are read outwards from the variable name, which is why you get the weirdness with static array dimensions in D.
- Jonathan M Davis
|
Copyright © 1999-2021 by the D Language Foundation