No. isForwardRange
è false
per gli array statici, perché non sono intervalli di inoltro validi. Devono avere uno front
valido, empty
e popFront
.
Un intervallo deve essere modificato mentre è iterato. popFront
rimuove il primo elemento dall'intervallo, riducendo la lunghezza dell'intervallo di uno. gli array statici non possono essere modificati. Gli elementi possono essere, ma non possono essere.
int[5] a;
a.length = 4;
è illegale. Pertanto, popFront
non può funzionare con gli array statici e pertanto gli array statici non possono essere intervalli.
front
, empty
, e popFront
sono dichiarati per gli array in std.array, e front
e empty
lavorerà con gli array statici, perché prendono esplicitamente array dinamici (non catene), e le matrici statiche possono essere implicitamente convertito in array dinamici quando una funzione assume una matrice dinamica (viene presa una porzione della matrice statica). Tuttavia, popFront
non funzionerà, perché richiede uno ref
di un array dinamico. E come ho fatto notare, non è possibile fare in modo che popFront
funzioni con gli array statici indipendentemente dall'implementazione di popFront
, perché non è possibile mutare una matrice statica come sarebbe necessaria per un intervallo.
Ora come per fill
, richiede un intervallo in avanti, non un array. Quindi, IFTI (istanza del modello di funzione implicita) proverà ad utilizzare il tipo di array statico (non il tipo di array dinamico) con esso. E poiché isForwardRange
è false
per un array statico, fill
non riesce a compilare con un array statico. Tuttavia, quando si suddivide l'array statico, si passa quindi a un array dinamico, per il quale isForwardRange
ètrue
. Quindi, funziona.E poiché la slice punta agli stessi elementi e fill
muta gli elementi e non la matrice, gli elementi nella matrice statica vengono modificati da fill
.
Diffidare, tuttavia, di passare fette di array statici alle funzioni. Finché esiste la matrice statica, va bene. Ma una volta che l'array statico lascia l'ambito, qualsiasi porzione di esso non è valida. Quindi, facendo qualcosa come
int[] foo()
{
int[5] a = [1, 2, 3, 4, 5]
return find(a[], 3);
}
sarebbe molto male. Un riferimento a a
sta sfuggendo a foo
- ovvero una porzione dei suoi ultimi 3 elementi.
Quindi, se si passa una porzione di una matrice statica a una funzione, è necessario assicurarsi che non vi siano riferimenti a tale matrice. fill
, tuttavia, dovrebbe andare bene.
Ho ragione nel dire che devi tagliare anche con 'Array' e' SList'? Sembra un po 'un difetto di progettazione. –
Non è proprio un difetto di progettazione IMHO. È più che mai un caso che gli array dinamici siano uno strano caso speciale di gamme. Ma dal momento che sono il caso più comune, è quello a cui siamo abituati. Un container dovrebbe convertirsi implicitamente al suo tipo di slice per IFTI in modo che non debba essere esplicitamente tagliato quando passa ad una funzione, e che renderebbe molto più difficile passare contenitori a funzioni basate su modelli. E non sono sicuro che sarebbe una buona idea che tutti i tipi affettabili fossero automaticamente affettati con IFTI in generale - anche quando si tratta solo di intervalli. –
Puoi pensare in questo modo. I contenitori, inclusi gli array statici, devono essere tagliati per ottenere un intervallo su di essi. Quindi, se si desidera un intervallo su di essi per qualsiasi motivo, incluso il passaggio a una funzione basata sull'intervallo, è necessario suddividerli esplicitamente. Ma gli array dinamici sono intervalli _already_ anziché contenitori, quindi non è necessario eseguire il slicing. –