2012-02-12 6 views
7

新しい配列でコンストラクタを呼び出すにはどうすればよいですか?配列でコンストラクタを使用するD

たとえば、次のコードでは、Aのインスタンス化ごとにコンストラクタをコールし、10個の要素すべてに対してbを5に初期化する方法を教えてください。

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

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

私はそれは不可能だ推測しているが、私は望むことができる...

答えて

11

単純なループを行う必要があります(そしてそれは最も読みやすいです)

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

値の型を扱う場合は、std.array.replicateを使用できます。

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

あなた参照型と同じことを行うことができますが、すべての要素が同じオブジェクトを参照しようとしている各要素は5である長さ50のint[]を作成します。

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

もしあなたが本当に1行でやりたいのであれば、あなたのためにマクロを書くことができます。私は他の答えから実際の初期化のためのコードを借りました。これはコンストラクタの引数を固定しているが、あなたはおそらくテンプレートに可変長引数を指定して何かをして、いくつかの可能性が

もちろん
A[] a = allocate!(A)(10, 5); 

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個の要素の配列全体を割り当てることができます正しいコンストラクタコールを生成するためにmixinsを使用します。

関連する問題