静态数组是向前范围吗?
这有效:
int[] a = [ 1, 2, 3, 4 ];
fill(a, 5);
但这不起作用:
int[4] a = [ 1, 2, 3, 4 ];
fill(a, 5);
并且我收到此错误:
错误:模板 std.algorithm.fill(Range,Value) if (isForwardRange!(Range) && is(typeof(range.front = Filler))) 与任何函数模板声明不匹配
与任何函数模板声明不匹配,我必须这样做为了使其能够与静态数组一起使用:
int[4] a = [ 1, 2, 3, 4 ];
fill(a[], 5);
有人可以解释一下这种行为吗?
This works:
int[] a = [ 1, 2, 3, 4 ];
fill(a, 5);
but this doesn't:
int[4] a = [ 1, 2, 3, 4 ];
fill(a, 5);
and I get this error:
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不可以。对于静态数组,
isForwardRange
为false
,因为它们不是有效的前向范围。它们必须具有有效的front
、empty
和popFront
。范围在迭代时必须发生变化。
popFront
从范围中删除第一个元素,将范围的长度减少一个。静态数组不能被改变。他们的元素可以是,但他们不能是。是非法的。因此,
popFront
无法使用静态数组,因此静态数组不能是范围。front
、empty
和popFront
在 std.array 中为数组声明,并且front
和empty
将使用静态数组,因为它们显式地采用动态数组(而不是范围),并且当函数采用动态数组(采用静态数组的切片)时,静态数组可以隐式转换为动态数组。但是,popFront
不起作用,因为它需要动态数组的ref
。正如我指出的那样,无论popFront
的实现如何,都无法使popFront
与静态数组一起使用,因为您无法像以前那样改变静态数组需要一个范围。现在对于
fill
,它需要一个向前的范围,而不是一个数组。因此,IFTI(隐式函数模板实例化)将尝试使用静态数组类型(而不是动态数组类型)。由于静态数组的isForwardRange
为false
,因此fill
无法使用静态数组进行编译。但是,当您对静态数组进行切片时,您将传递一个动态数组,其中isForwardRange
istrue
。所以,它有效。因为切片指向相同的元素,而fill
会改变元素而不是数组,所以静态数组中的元素会被fill
改变。但是,在将静态数组切片传递给函数时要小心。只要静态数组存在就可以。但是一旦静态数组离开作用域,它的任何切片都将无效。所以,做这样的事情
是非常糟糕的。对
a
的引用正在转义foo
- 即最后 3 个元素的切片。因此,如果将静态数组的切片传递给函数,则需要确保没有对该数组的引用逃逸。不过,
fill
应该没问题。No.
isForwardRange
isfalse
for static arrays, because they're not valid forward ranges. They must have a validfront
,empty
, andpopFront
.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.is illegal. So,
popFront
cannot work with static arrays and therefore static arrays cannot be ranges.front
,empty
, andpopFront
are declared for arrays in std.array, andfront
andempty
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 aref
of a dynamic array. And as, I pointed out,popFront
can't be made to work with static arrays regardless ofpopFront
's implementation, because you can't mutate a static array as would be required for a range.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 sinceisForwardRange
isfalse
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 whichisForwardRange
istrue
. So, it works. And because, the slice points to the same elements, andfill
mutates the elements and not the array, the elements in the static array are mutated byfill
.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
would be very bad. A reference to
a
is escapingfoo
- 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.isForwardRange
检查front
、empty
属性和popfront()
函数是否存在,问题在于
popfront()
需要缩小数组,因为您(应该)知道您无法调整静态数组的大小,但可以调整静态数组的切片(本质上是普通的动态数组)的大小(当然这是不影响静态数组)为了澄清
a.popfront()
需要将 a 从int[4]
转换为int[3]
但这是不可能的isForwardRange
checks for the existence of thefront
,empty
properties andpopfront()
functionthe issue is that
popfront()
would need to shrink the array, as you (should) know you can't resize a static array but a slice of a static array (essentially a normal dynamic array) can be resized (this of course doesn't affect the static array)to clarify
a.popfront()
would need to transform a fromint[4]
toint[3]
but that's not possible