No. isForwardRange
es false
para matrices estáticas, ya que no son intervalos de avance válidos. Deben tener un válido front
, empty
y popFront
.
Un rango debe ser mutado a medida que se itera. popFront
elimina el primer elemento del rango, reduciendo la longitud del rango en uno. arrays estáticos no pueden ser mutados. Sus elementos pueden ser, pero no pueden ser.
int[5] a;
a.length = 4;
es ilegal. Por lo tanto, popFront
no puede trabajar con matrices estáticas y, por lo tanto, las matrices estáticas no pueden ser intervalos.
front
, empty
, y popFront
se declaran para matrices en std.array, y front
y empty
trabajará con matrices estáticas, ya que explícitamente toman matrices dinámicas (no rangos), y matrices estáticas se puede convertir implícitamente a matrices dinámicas cuando una función toma una matriz dinámica (se toma una porción de la matriz estática). Sin embargo, popFront
no funcionará, ya que requiere un ref
de una matriz dinámica. Y como, señalé, popFront
no se puede hacer para trabajar con matrices estáticas independientemente de la implementación de popFront
, porque no se puede mutar una matriz estática como sería necesario para un rango.
Ahora, como para fill
, toma un rango de avance, no una matriz. Entonces, IFTI (instanciación de plantilla de función implícita) intentará y usará el tipo de matriz estática (no el tipo de matriz dinámica) con ella. Y dado que isForwardRange
es false
para una matriz estática, fill
no se puede compilar con una matriz estática. Sin embargo, cuando segmenta la matriz estática, está pasando una matriz dinámica, para la cual isForwardRange
estrue
. Entonces, funcionaY debido a que el corte señala a los mismos elementos y fill
muta los elementos y no la matriz, los elementos en la matriz estática están mutados por fill
.
Tenga cuidado, sin embargo, de pasar porciones de arreglos estáticos a las funciones. Mientras exista la matriz estática, está bien. Pero una vez que la matriz estática deja alcance, cualquier porción de la misma no es válida. Por lo tanto, haciendo algo como
int[] foo()
{
int[5] a = [1, 2, 3, 4, 5]
return find(a[], 3);
}
sería muy malo. Una referencia a a
está escapando foo
, es decir, una porción de sus últimos 3 elementos.
Por lo tanto, si está pasando una porción de una matriz estática a una función, debe asegurarse de que no haya referencias a esa matriz. fill
, sin embargo, debería estar bien.
¿Tengo razón al decir que también debes cortar con 'Array' y' SList'? Parece un poco un defecto de diseño. –
No es realmente un defecto de diseño en mi humilde opinión. Es más un caso que las matrices dinámicas son un extraño caso especial de rangos. Pero dado que actualmente son el caso más común, es a lo que estamos acostumbrados. Un contenedor debería convertir implícitamente a su tipo de sector para IFTI para que no tenga que cortarse explícitamente al pasar a una función, y eso haría mucho más difícil pasar contenedores a funciones con plantilla. Y no estoy seguro de que sea una buena idea que todos los tipos rebanables se corten automáticamente con IFTI en general, incluso cuando se trata solo de rangos. –
Puedes pensarlo así. Los contenedores, incluidas las matrices estáticas, deben dividirse para obtener un rango sobre ellos. Por lo tanto, si desea un rango sobre ellos por cualquier motivo, incluido el paso a una función basada en el rango, debe dividirlos explícitamente. Pero los arreglos dinámicos ya tienen rangos en lugar de contenedores, por lo que no es necesario cortarlos. –