静态数组是一个正向范围吗? [英] is a static array a forward range?
问题描述
这有效:
int[] a = [ 1, 2, 3, 4 ];
fill(a, 5);
但这不是:
int[4] a = [ 1, 2, 3, 4 ];
fill(a, 5);
,我收到此错误:
错误:如果(isForwardRange!(Range)&& is(typeof(range.front = filler)))与任何函数模板声明都不匹配,则模板std.algorithm.fill(Range,Value)
Error: template std.algorithm.fill(Range,Value) if (isForwardRange!(Range) && is(typeof(range.front = filler))) does not match any function template declaration
相反,我必须这样做才能使其与静态数组一起工作:
instead, I have to do this in order for it to work with static arrays:
int[4] a = [ 1, 2, 3, 4 ];
fill(a[], 5);
有人可以解释这种现象吗?
could any one explain this behavior please?
推荐答案
否。对于静态数组, isForwardRange
为 false
,因为它们不是有效的正向范围。它们必须具有有效的 front
, empty
和 popFront
No. isForwardRange
is false
for static arrays, because they're not valid forward ranges. They must have a valid front
, empty
, and popFront
.
范围必须在迭代时进行更改。 popFront
从范围中删除第一个元素,将范围的长度减少一个。静态数组不能突变。他们的元素可以,但是不能。
A range must be mutated as it's iterated over. popFront
removes the first element from the range, reducing the length of the range by one. static arrays cannot be mutated. Their elements can be, but they can't be.
int[5] a;
a.length = 4;
是非法的。因此, popFront
不能用于静态数组,因此静态数组不能是范围。
is illegal. So, popFront
cannot work with static arrays and therefore static arrays cannot be ranges.
为std.array中的数组声明了front
, empty
和 popFront
code> front 和 empty
将与静态数组一起使用,因为它们显式采用动态数组(而不是范围),并且静态数组可以当函数采用动态数组(采用静态数组的一部分)时,隐式转换为动态数组。但是, popFront
不起作用,因为它需要动态数组的 ref
。正如我指出的那样,无论 popFront
的实现如何,都无法使 popFront
与静态数组一起使用,因为您不能按照某个范围的要求更改静态数组。
front
, empty
, and popFront
are declared for arrays in std.array, and front
and empty
will work with static arrays, because they explicitly take dynamic arrays (not ranges), and static arrays can be implicitly converted to dynamic arrays when a function takes a dynamic array (a slice of the static array is taken). However, popFront
won't work, because it requires a ref
of a dynamic array. And as, I pointed out, popFront
can't be made to work with static arrays regardless of popFront
's implementation, because you can't mutate a static array as would be required for a range.
现在,对于 fill
,它需要一个正向范围,而不是数组。因此,IFTI(隐式函数模板实例化)将尝试使用静态数组类型(而不是动态数组类型)。并且由于静态数组的 isForwardRange
为 false
,因此 fill
无法使用静态数组进行编译。但是,在对静态数组进行切片时,您将传递动态数组,为此动态数组 isForwardRange
是 true
。因此,它有效。而且由于切片指向相同的元素,并且 fill
会更改元素而不是数组,因此静态数组中的元素会被 fill更改。
。
Now as for fill
, it takes a forward range, not an array. So, IFTI (implicit function template instantiation) will try and use the static array type (not the dynamic array type) with it. And since isForwardRange
is false
for a static array, fill
fails to compile with a static array. However, when you slice the static array, you're then passing a dynamic array, for which isForwardRange
is true
. So, it works. And because, the slice points to the same elements, and fill
mutates the elements and not the array, the elements in the static array are mutated by fill
.
但是要警惕将静态数组的切片传递给函数。只要存在静态数组,就可以了。但是,一旦静态数组离开作用域,它的任何切片都将无效。因此,做类似
Be wary, however, of passing slices of static arrays to functions. As long as the static array exists, it's fine. But once the static array leaves scope, any slice of it is then invalid. So, doing something like
int[] foo()
{
int[5] a = [1, 2, 3, 4, 5]
return find(a[], 3);
}
会很糟糕。对 a
的引用正在转义 foo
-即其最后三个元素的一部分。
would be very bad. A reference to a
is escaping foo
- namely a slice of its last 3 elements.
因此,如果要将静态数组的一部分传递给函数,则需要确保没有对该数组的引用转义。 填充
应该没问题。
So, if you are passing a slice of a static array to a function, you need to be sure that no references to that array escape. fill
, however, should be fine.
这篇关于静态数组是一个正向范围吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!