静态数组是一个正向范围吗? [英] is a static array a forward range?

查看:90
本文介绍了静态数组是一个正向范围吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这有效:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆