这有效:
int[] a = [ 1, 2, 3, 4 ];
fill(a, 5);
Run Code Online (Sandbox Code Playgroud)
但这不是:
int[4] a = [ 1, 2, 3, 4 ];
fill(a, 5);
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
错误:模板std.algorithm.fill(Range,Value)if(isForwardRange!(Range)&&是(typeof(range.front = filler)))与任何函数模板声明都不匹配
相反,我必须这样做才能使它与静态数组一起使用:
int[4] a = [ 1, 2, 3, 4 ];
fill(a[], 5);
Run Code Online (Sandbox Code Playgroud)
请问任何人解释这种行为吗?
isForwardRange将检查的存在front,empty性质和popfront()功能
问题是popfront()需要缩小数组,因为你(应该)知道你不能调整静态数组的大小,但是可以调整静态数组的切片(本质上是普通的动态数组)(这当然不会影响静态数组)
澄清a.popfront()将需要转换为int[4],int[3]但这是不可能的
号isForwardRange是false静态数组,因为他们没有有效的前进档位.他们必须有一个有效的front,empty和popFront.
一个范围必须在迭代时进行变异.popFront从范围中移除第一个元素,将范围的长度减少一个.静态数组不能变异.他们的元素可以,但他们不可能.
int[5] a;
a.length = 4;
Run Code Online (Sandbox Code Playgroud)
是非法的.因此,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);
}
Run Code Online (Sandbox Code Playgroud)
会很糟糕的.引用a是逃避foo- 即其最后3个元素的一部分.
因此,如果要将一个静态数组的片段传递给函数,则需要确保没有对该数组的引用转义.fill但是,应该没问题.