静态数组是向前范围吗?

发布于 2024-12-27 06:55:31 字数 468 浏览 1 评论 0原文

这有效:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦一生花开无言 2025-01-03 06:55:31

不可以。对于静态数组,isForwardRangefalse,因为它们不是有效的前向范围。它们必须具有有效的 frontemptypopFront

范围在迭代时必须发生变化。 popFront 从范围中删除第一个元素,将范围的长度减少一个。静态数组不能被改变。他们的元素可以是,但他们不能是。

int[5] a;
a.length = 4;

是非法的。因此,popFront 无法使用静态数组,因此静态数组不能是范围。

frontemptypopFront 在 std.array 中为数组声明,并且 frontempty 将使用静态数组,因为它们显式地采用动态数组(而不是范围),并且当函数采用动态数组(采用静态数组的切片)时,静态数组可以隐式转换为动态数组。但是,popFront 不起作用,因为它需要动态数组的 ref。正如我指出的那样,无论 popFront 的实现如何,都无法使 popFront 与静态数组一起使用,因为您无法像以前那样改变静态数组需要一个范围。

现在对于fill,它需要一个向前的范围,而不是一个数组。因此,IFTI(隐式函数模板实例化)将尝试使用静态数组类型(而不是动态数组类型)。由于静态数组的 isForwardRangefalse,因此 fill 无法使用静态数组进行编译。但是,当您对静态数组进行切片时,您将传递一个动态数组,其中 isForwardRange is true。所以,它有效。因为切片指向相同的元素,而 fill 会改变元素而不是数组,所以静态数组中的元素会被 fill 改变。

但是,在将静态数组切片传递给函数时要小心。只要静态数组存在就可以。但是一旦静态数组离开作用域,它的任何切片都将无效。所以,做这样的事情

int[] foo()
{
    int[5] a = [1, 2, 3, 4, 5]
    return find(a[], 3);
}

是非常糟糕的。对 a 的引用正在转义 foo - 即最后 3 个元素的切片。

因此,如果将静态数组的切片传递给函数,则需要确保没有对该数组的引用逃逸。不过,fill 应该没问题。

No. isForwardRange is false for static arrays, because they're not valid forward ranges. They must have a valid front, empty, and 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;

is illegal. So, popFront cannot work with static arrays and therefore static arrays cannot be ranges.

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.

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);
}

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.

灰色世界里的红玫瑰 2025-01-03 06:55:31

isForwardRange 检查 frontempty 属性和 popfront() 函数是否存在,

问题在于 popfront() 需要缩小数组,因为您(应该)知道您无法调整静态数组的大小,但可以调整静态数组的切片(本质上是普通的动态数组)的大小(当然这是不影响静态数组)

为了澄清 a.popfront() 需要将 a 从 int[4] 转换为 int[3] 但这是不可能的

isForwardRange checks for the existence of the front, empty properties and popfront() function

the 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 from int[4] to int[3] but that's not possible

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文