Question

Désolé, cela est devenu une question 3 fois en ce qui concerne les tableaux

Je pense que les tableaux (de dynamique) sont vraiment puissants dans D, mais ce qui suit me tracasse depuis un certain temps:

En C ++ je pourrais facilement allouer un tableau avec des valeurs désignées, mais D je n'ai pas trouvé un moyen de le faire. Certes, ce qui suit est pas un problème:

int[] a = new int[N];
a[] = a0;

Mais il semble inefficace, car une ligne initialise avec 0, et comme 2 avec a0. Pourrait quelque chose de similaire à ce qui suit se faire en D?

int[] a = new int(a0)[N]; // illegal

Une autre question d'efficacité je lors de l'utilisation dans la foulée 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;
}

Certes, je pensais naïve que je pourrais simplement utiliser la foulée pour créer un nouveau tableau sans copier les éléments de it? Il n'y a aucun moyen de le faire dans D, droit?


Je suis donc allé et simulé comme si le tableau était comme foulée retournerait, et mis en œuvre f comme:

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

serait là un moyen de la place écrire get (x) en utilisant l'opérateur d'index get[x]? De cette façon, je pouvais statiquement mixin / inclure la fonction get de grandes enjambées et garder le reste de la fonction similaire. Je serais intéressé par l'approche adoptée, car une struct locale ne peut pas fonction d'accès des variables de portée (pourquoi pas?).

Était-ce utile?

La solution

Mais il semble inefficace, car une ligne initialise avec 0, et comme 2 avec a0. Pourrait quelque chose de similaire à ce qui suit se faire en D?

Utilisez std.array.uninitializedArray

S[] s = uninitializedArray!(S[])(N);
s[] = a0; 

Certes, je pensais naïve que je pourrais simplement utiliser la foulée pour créer un nouveau tableau sans copier les éléments de it? Il n'y a aucun moyen de le faire dans D, droit?

Votre f fonction a un S[] comme argument, ce qui est différent de ce que revient stride. La façon D pour résoudre ce problème est de faire fonctionner votre f accepter une plage en faisant un modèle:

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

S[] s = new S[10];
f(s); // works
f(stride(s, 3)); // works too

Vous pouvez aussi copier le tableau:

f(array(stride(s, 3)));

Mais vous voulez probablement éviter de copier le tableau entier si elle est grande.


serait là un moyen de la place écrire get (x) en utilisant l'opérateur d'index get [x]? De cette façon, je pouvais statiquement mixin / inclure la fonction Franchir get et garder le reste de la fonction similaire. Je serais intéressé par l'approche adoptée, car une struct locale ne peut pas fonction d'accès des variables de portée (pourquoi pas?).

Vous pouvez surcharger l'opérateur d'indexation dans votre propre 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;
}

Ceci est (un peu) la façon dont la fonction stride réelle fonctionne. Je recommande la lecture sur Plages .

Autres conseils

vous pouvez dupliquer (créer une copie) un tableau avec .dup (ce sera aussi le travail avec des tranches) ou vous pouvez définir les éléments avec le tableau initialiseur

int[] a=a0.dup;
int[] b=[e1,e2,e3];

vous pouvez faire le f générique (la foulée () retourne une struct que vous pouvez parcourir, pas un tableau)

void f(Z)(Z s)if(isInputRange!Z){
    foreach(elem;s){
         //...
    }
}

Rappelez-vous que les tableaux sont essentiellement structs avec un champ de pointeur sur un certain bloc de mémoire et un champ de taille

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top