Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using constructors with arrays in D

How do you call constructors when allocating an array with new?

For example, in the following code how would I call the constructor for each instantiation of A, initialising b to 5 for all 10 elements?

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

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

I'm guessing it's not possible, but I can hope...

like image 785
John_C Avatar asked Feb 12 '12 15:02

John_C


People also ask

Can a constructor be an array?

An array constructor can be used to define only an ordinary array with elements that are not a row type. An array constructor cannot be used to define an associative array or an ordinary array with elements that are a row type.

Can we pass array in constructor?

Array constructor with a single parameterArrays can be created using a constructor with a single number parameter. An array with its length property set to that number and the array elements are empty slots.

Can you put an array in a constructor Java?

One way to initialize the array of objects is by using the constructors. When you create actual objects, you can assign initial values to each of the objects by passing values to the constructor. You can also have a separate member method in a class that will assign data to the objects.

Does the constructor automatically initialize an array?

When you create an array, it's always initially populated with the default value for the type - which for a class is always a null reference.


3 Answers

a simple loop should do (and it's the most readable)

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

or you can use the array initializer:

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)];
like image 143
ratchet freak Avatar answered Oct 08 '22 22:10

ratchet freak


If you're dealing with a value type, you can use std.array.replicate.

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

would create an int[] of length 50 where each element is 5. You can do the same with a reference type, but all of the elements are going to refer to the same object.

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

will only call A's constructor once, and you'll end up with an A[] where all of the elements refer to the same object. If you want them to refer to separate objects, you're either going to have to set each element individually

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

or initialize the whole array with a literal

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

But that clearly will only work for relatively small arrays.

like image 38
Jonathan M Davis Avatar answered Oct 08 '22 22:10

Jonathan M Davis


If you really want to do it in one line, you could write a macro to do it for you. I've borrowed code for the actual initialisation from the other answers.

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

Then you can allocate an entire array of 10 elements at once with:

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

Of course this has fixed constructor arguments, but you could probably do something with variadic arguments to the template and some mixins to generate the correct constructor call.

like image 34
Kothar Avatar answered Oct 08 '22 22:10

Kothar