二维的动态数组初始化,步幅和索引操作 [英] D dynamic array initialization, stride and the index operation
问题描述
对不起,这成为对数组3倍的问题。
我认为(动态)阵列是在D中真正强大的,但下面已经困扰了我一段时间:
在C ++中我可以轻松地与指定的值分配一个数组,但在D我还没有找到一种方式来做到这一点。当然,下面是没有问题的:
INT [] A = INT新[N];
一个[] = A0;
但看上去效率低,因为一行将与 0
初始化,而像2 A0
。可以与以下类似的东西在D中做什么?
INT [] A = INT新(A0)[N]; //非法
另一个效率无论我在std.range使用时的步幅有:
进口std.stdio;
进口std.range;的struct
{
INT X; 这(本)
{
writeln(复制,X);
}
}无效F(S [] S)
{
}诠释的main()
{
S [] S =新S [10];
的foreach(我,裁判伏; S)
{
V.X = I;
} F(步幅(S,3)); //错误
返回0;
}
当然,我是天真的想法我可以简单地用步幅不复制它的元素,创造出一个新的数组?有没有办法在D中这样做,对吧?
于是我就和模拟为如果阵列作为步幅将返回,并实施˚F
为:
F(S,3);无效F(S [] S,UINT步幅)
{
REF小号弄(UINT I)
{
断言(我*步幅< s.length);
返回小号[我*步幅]
} 对于(UINT X ...)
{
得到(X)= ...;
}
}
会不会有使用索引操作符的方式,而不是写得到(X) GET [X]
?这样我可以静态地混入/包括跨步 GET
功能,并保持类似功能的其余部分。我很想在所采取的方法,因为当地的结构是不允许访问函数范围内的变量(为什么不呢?)。
但看上去效率低,因为一行将与0初始化,而像2 A0。可以与以下类似的东西在D中做什么?
块引用>使用
std.array.uninitializedArray
S [] S = uninitializedArray(S [])(N)!;
S [] = A0;
当然,我是天真的想法我可以简单地用步幅不复制它的元素,创造出一个新的数组?有没有办法在D中这样做,对吧?
块引用>您函数
˚F
有一个S []
作为一个参数,它是从什么<$ C $不同C>步幅的回报。对D的方式来解决,这是使你的˚F
功能通过使模板接受任何范围:无效F(范围)(范围S)
{
的foreach(项目; S)
//利用项目
}S [] S =新S [10];
F(S); //作品
F(步幅(S,3)); //工程太另外,您可以在阵列复制:
F(阵列(步幅(S,3)));
但你可能想避免复制整个数组,如果是大的。
会不会有使用索引运算得到[X],而不是写得到(X)的方法吗?这样我可以静态地混入/包括跨越式get函数,并保持类似功能的其余部分。我很想在所采取的方法,因为当地的结构是不允许访问函数范围内的变量(为什么不呢?)。
块引用>您可以在自己的结构重载索引运算符。
结构StrideArray
{
该(S [] S,UINT步幅){m_array = S; m_stride =步幅; } 小号opIndex(为size_t我){返回小号[我* m_stride] }
无效opIndexAssign(为size_t I,S值){S [I * m_stride] =价值; } 私人S [] m_array;
私人UINT m_stride;
}这是(种)的实际
步幅
函数的工作方式。我建议你在范围读了。Sorry, this became a 3-fold question regarding arrays
I think (dynamic) arrays are truly powerful in D, but the following has been bothering me for a while:
In C++ I could easily allocate an array with designated values, but in D I haven't found a way to do so. Surely the following is no problem:
int[] a = new int[N]; a[] = a0;
But it looks inefficient, since line one will initialize with
0
, and like 2 witha0
. Could something similar to the following be done in D?int[] a = new int(a0)[N]; // illegal
Another efficiency matter I have when using stride in std.range:
import std.stdio; import std.range; struct S { int x; this(this) { writeln("copy ", x); } } void f(S[] s) { } int main() { S[] s = new S[10]; foreach (i, ref v; s) { v.x = i; } f(stride(s, 3)); // error return 0; }
Surely I was naive thinking I could simply use stride to create a new array without copying it's elements? There is no way to do so in D, right?
So I went and simulated as if the array was as stride would return, and implemented
f
as:f(s, 3); void f(S[] s, uint stride) { ref S get(uint i) { assert (i * stride < s.length); return s[i * stride]; } for (uint x ... ) { get(x) = ...; } }
Would there be a way to instead write get(x) using the index operator
get[x]
? This way I could statically mixin / include the stridingget
function and keep the rest of the function similar. I'd be interested in the approach taken, since a local struct is not allowed to access function scope variables (why not?).解决方案But it looks inefficient, since line one will initialize with 0, and like 2 with a0. Could something similar to the following be done in D?
Use
std.array.uninitializedArray
S[] s = uninitializedArray!(S[])(N); s[] = a0;
Surely I was naive thinking I could simply use stride to create a new array without copying it's elements? There is no way to do so in D, right?
Your function
f
has anS[]
as an argument, which is different from whatstride
returns. The D way to solve this is to make yourf
function accept any range by making it a template:void f(Range)(Range s) { foreach (item; s) // use item } S[] s = new S[10]; f(s); // works f(stride(s, 3)); // works too
Alternatively you can copy the array:
f(array(stride(s, 3)));
But you probably want to avoid copying the entire array if it is large.
Would there be a way to instead write get(x) using the index operator get[x]? This way I could statically mixin / include the striding get function and keep the rest of the function similar. I'd be interested in the approach taken, since a local struct is not allowed to access function scope variables (why not?).
You can overload the indexing operator in your own struct.
struct StrideArray { this(S[] s, uint stride) { m_array = s; m_stride = stride; } S opIndex(size_t i) { return s[i * m_stride]; } void opIndexAssign(size_t i, S value) { s[i * m_stride] = value; } private S[] m_array; private uint m_stride; }
This is (kind of) the way the actual
stride
function works. I'd recommend reading up on Ranges.这篇关于二维的动态数组初始化,步幅和索引操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!