Ответ 1
Нет. isForwardRange
false
для статических массивов, поскольку они не являются допустимыми диапазонами вперед. Они должны иметь действительные front
, empty
и popFront
.
Диапазон должен быть мутированным по мере его повторения. popFront
удаляет первый элемент из диапазона, уменьшая длину диапазона на единицу. статические массивы не могут быть мутированы. Их элементы могут быть, но они не могут быть.
int[5] a;
a.length = 4;
является незаконным. Таким образом, popFront
не может работать со статическими массивами, поэтому статические массивы не могут быть диапазонами.
front
, empty
и popFront
объявляются для массивов в std.array, а front
и empty
будут работать со статическими массивами, поскольку они явно принимают динамические массивы (а не диапазоны) и статические массивы могут быть неявно преобразованы в динамические массивы, когда функция принимает динамический массив (берется срез статического массива). Однако popFront
не будет работать, потому что для него требуется ref
динамического массива. И, как я заметил, popFront
невозможно заставить работать со статическими массивами независимо от реализации popFront
, потому что вы не можете мутировать статический массив, как это требуется для диапазона.
Теперь, что касается fill
, он принимает диапазон вперед, а не массив. Таким образом, IFTI (имплицирование неявных функций) будет пытаться использовать с ним тип статического массива (а не тип динамического массива). А поскольку isForwardRange
false
для статического массива, fill
не может скомпилироваться со статическим массивом. Однако, когда вы нарезаете статический массив, вы затем передаете динамический массив, для которого isForwardRange
является true
. Таким образом, он работает. И поскольку срез указывает на те же элементы, а fill
мутирует элементы, а не массив, элементы в статическом массиве мутируются с помощью fill
.
Будьте осторожны, однако, о передаче срезов статических массивов в функции. Пока существует статический массив, это прекрасно. Но как только статический массив покинет область видимости, любой ее фрагмент окажется недействительным. Итак, что-то вроде
int[] foo()
{
int[5] a = [1, 2, 3, 4, 5]
return find(a[], 3);
}
будет очень плохо. Ссылка на a
выводит foo
- а именно срез его последних 3 элементов.
Итак, если вы передаете срез статического массива функции, вы должны быть уверены, что ссылки на этот массив не исчезают. fill
, однако, должно быть хорошо.