Использование конструкторов с массивами в D - PullRequest
7 голосов
/ 12 февраля 2012

Как вы вызываете конструкторы при выделении массива с новым?

Например, в следующем коде, как бы я вызвал конструктор для каждого экземпляра A, инициализируя b в 5 для всех 10 элементов?1003 *

void main() {
    A[] a = new A[10];
}

class A {
    int b;
    this(int init) {
        b = init;
    }
}

Полагаю, это невозможно, но я могу надеяться ...

Ответы [ 3 ]

11 голосов
/ 12 февраля 2012

должен делать простой цикл (и он наиболее читабелен)

foreach(ref el;a){
    el=new A(5);
}

или вы можете использовать инициализатор массива:

A[] a=[new A(5),new A(5),new A(5),new A(5),new A(5),
       new A(5),new A(5),new A(5),new A(5),new A(5)];
4 голосов
/ 13 февраля 2012

Если вы имеете дело с типом значения, вы можете использовать std.array.replicate.

auto a = replicate([5], 50);

создаст int[] длины 50, где каждый элемент равен 5. Вы может сделать то же самое со ссылочным типом, но все элементы будут ссылаться на один и тот же объект.

auto a = replicate([new A(5)], 50);

вызовет конструктор A только один раз, и вызаканчивается A[], где все элементы относятся к одному и тому же объекту.Если вы хотите, чтобы они ссылались на отдельные объекты, вам придется либо устанавливать каждый элемент индивидуально

auto a = new A[](50);
foreach(ref e; a)
    e = new A(5);

, либо инициализировать весь массив литералом

auto a = [new A(5), new A(5), new A(5)];

Ноочевидно, будет работать только для сравнительно небольших массивов.

1 голос
/ 19 февраля 2012

Если вы действительно хотите сделать это в одну строку, вы можете написать макрос, который сделает это за вас. Я заимствовал код для фактической инициализации из других ответов.

template allocate(T) {
    T[] allocate(int size, int arg) {
        T[] result = new T[size];
        foreach(ref el; result)
            el=new T(arg);
        return result;
    }
}

Затем вы можете выделить весь массив из 10 элементов одновременно с помощью:

A[] a = allocate!(A)(10, 5);

Конечно, здесь есть фиксированные аргументы конструктора, но вы, вероятно, могли бы что-то сделать с переменными аргументами шаблона и некоторыми миксинами для генерации правильного вызова конструктора.

...