D动态数组初始化,步幅和索引操作

Tac*_*lff 4 arrays d dynamic stride

对不起,这成了关于阵列的3个问题

我认为(动态)数组在D中真正强大,但以下一直困扰我一段时间:

在C++中,我可以轻松地分配具有指定值的数组,但在DI中没有找到一种方法.当然以下是没有问题的:

int[] a = new int[N];
a[] = a0;
Run Code Online (Sandbox Code Playgroud)

但它看起来效率低下,因为第一行将初始化0,并且像2一样a0.可以在D中完成类似以下的操作吗?

int[] a = new int(a0)[N]; // illegal
Run Code Online (Sandbox Code Playgroud)

在std.range中使用stride时我遇到的另一个效率问题:

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;
}
Run Code Online (Sandbox Code Playgroud)

当然我天真地想,我可以简单地使用步幅创建一个新的数组而不复制它的元素?在D中没有办法这样做,对吧?


所以我去模拟,好像数组一样大步返回,并实现f为:

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) = ...;
    }
}
Run Code Online (Sandbox Code Playgroud)

是否有办法使用索引运算符编写get(x)get[x]?这样我就可以静态混合/包含跨步get功能,并保持功能的其余部分相似.我对所采用的方法感兴趣,因为不允许本地结构访问函数范围变量(为什么不呢?).

Pet*_*der 7

但它看起来效率低下,因为第一行将初始化为0,而2与a0初始化.可以在D中完成类似以下的操作吗?

使用 std.array.uninitializedArray

S[] s = uninitializedArray!(S[])(N);
s[] = a0; 
Run Code Online (Sandbox Code Playgroud)

当然我天真地想,我可以简单地使用步幅创建一个新的数组而不复制它的元素?在D中没有办法这样做,对吧?

你的函数f有一个S[]参数,它与stride返回的不同.解决这个问题的D方法是让你的f函数接受任何范围,使其成为一个模板:

void f(Range)(Range s)
{
    foreach (item; s)
        // use item
}

S[] s = new S[10];
f(s); // works
f(stride(s, 3)); // works too
Run Code Online (Sandbox Code Playgroud)

或者,您可以复制数组:

f(array(stride(s, 3)));
Run Code Online (Sandbox Code Playgroud)

但是如果它很大,你可能想避免复制整个数组.


是否有办法使用索引运算符get [x]来编写get(x)?这样我就可以静态混合/包含跨步get函数并保持函数的其余部分相似.我对所采用的方法感兴趣,因为不允许本地结构访问函数范围变量(为什么不呢?).

您可以在自己的结构中重载索引运算符.

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;
}
Run Code Online (Sandbox Code Playgroud)

这是(某种)实际stride功能的工作方式.我建议你阅读Ranges.