verdadera valor una tal que multiplicacion matriz matriciales matricial matrices incognitas hallar hace encuentre ecuación ecuaciones determine despejar con cada 3x3 delphi generics casting delphi-xe2 dynamic-arrays

delphi - valor - ¿Es seguro tipear la conversión de TABLA<X> a una matriz de X?



multiplicacion de matrices con incognitas (3)

Hoy descubrí un error de compilación ( QC#108577 ).

El siguiente programa no se compila:

program Project1; {$APPTYPE CONSOLE} procedure P(M: TArray<TArray<Integer>>); begin SetLength(M, 1, 2); end; begin end.

El compilador se SetLength en la línea SetLength y dice:

[dcc32 Error] E2029 '')'' expected but '','' found

Sé que podría arreglarlo así:

procedure P(M: TArray<TArray<Integer>>); var i: Integer; begin SetLength(M, 1); for i := low(M) to high(M) do SetLength(M[i], 2); end;

Pero, naturalmente, estoy dispuesto a evitar tener que recurrir a esto.

La siguiente variante compila y parece funcionar:

procedure P(M: TArray<TArray<Integer>>); type TArrayOfArrayOfInteger = array of array of Integer; begin SetLength(TArrayOfArrayOfInteger(M), 1, 2); end;

No sé lo suficiente acerca de los detalles de implementación de los arreglos dinámicos, la TArray<T> , el recuento de referencias, etc. para estar seguro de que esto es seguro.

¿Hay alguien por ahí que sepa lo suficiente como para decir de una manera u otra si esto producirá el código correcto en el tiempo de ejecución?


El procedimiento intrínseco del compilador SetLength construye una matriz de dimensiones sobre la marcha en la pila y llama a DynArraySetLength para cualquier matriz dinámica, ya sea genérica o no. Si una matriz genérica no fuera estructuralmente compatible con una matriz dinámica regular, posiblemente no se llamaría la misma implementación para establecer la longitud.

De hecho, la documentation de DynArraySetLength ofrece SetLength como una alternativa para arreglos multidimensionales. DynArraySetLength también podría usarse en lugar de un encasillado, pero no veo ninguna razón para preferir una u otra.


Recientemente fui mordido por el hecho de que DynamicArray<T> y TArray<T> en C ++ se implementan de manera diferente ( DynamicArray es una clase independiente, mientras que TArray es un descendiente TObject ), lo que implica que la array of T y TArray<T> hacen También tienen algunas diferencias de implementación en Delphi. Ciertamente producen al menos diferentes tipos de RTTI. ¿Cuál fue la causa raíz de un problema en algunos de mis códigos C ++ que comenzaron a fallar cuando el compilador Delphi comenzó a TArray en archivos HPP para la array of ... Delphi array of ... tipos array of ... lugar de DynamicArray de DynamicArray ?


Mediante el diseño de la implementación de genéricos, funcionará el uso de un mapa manual para una array of array of Integer .

¡Pero aquí no hay beneficio de usar genéricos!

Sólo el código:

type TArrayOfArrayOfInteger = array of array of Integer; procedure P(M: TArrayOfArrayOfInteger); begin SetLength(TArrayOfArrayOfInteger, 1, 2); end;

Tenga en cuenta también que dicho TArray<> o array of .. se pasan por valor y se copian en la pila, a menos que especifique const o var :

procedure P(var M: TArrayOfArrayOfInteger); begin SetLength(TArrayOfArrayOfInteger, 1, 2); end; // now caller instance of the parameter will be resized var A: TArrayOfArrayOfInteger; ... A := nil; P(A); assert(length(A)=1); assert(length(A[0])=2);