digitalmars.D.learn - Creating an array of default-constructed class instances
- Simon (14/14) Feb 09 2013 Hi, I'm new to the D programming language. Overall I'm liking
- Maxim Fomin (5/20) Feb 09 2013 You can create separate function which fills array with instances
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (20/34) Feb 09 2013 Here is one way:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (4/5) Feb 09 2013 Actually, without the extra parentheses:
- Simon (4/9) Feb 09 2013 It's a shame there isn't any simple syntax for it, but that's
- Philippe Sigaud (29/34) Feb 10 2013 Oh, you can easily use a template:
- Jos van Uden (15/29) Feb 10 2013 import std.stdio, std.algorithm;
- monarch_dodra (5/45) Feb 10 2013 HELL NO!!!!
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (6/11) Feb 10 2013 And in case that is what we really wanted, there is the simpler but
- monarch_dodra (15/30) Feb 10 2013 The difference is that C++ will *place* the instances inside the
Hi, I'm new to the D programming language. Overall I'm liking things very much, but I'm still getting the hang of a few things. Here's a basic programming pattern: I have a class called Thing, and while I'm coding I decide I need N Thing instances. In C++ that's a matter of std::vector<Thing> things(N); In python, I can use a list comprehension. things = [Thing() for _ in range(N)] However, the obvious D version doesn't work. auto things = new Thing[N]; Because Thing.init is null, this produces an array of null references. Of course, I can write a for loop to fill in the array after creation, but this feels very un-D-like. Is there a straightforward way to create a bunch of class instances?
Feb 09 2013
On Sunday, 10 February 2013 at 06:14:37 UTC, Simon wrote:Hi, I'm new to the D programming language. Overall I'm liking things very much, but I'm still getting the hang of a few things. Here's a basic programming pattern: I have a class called Thing, and while I'm coding I decide I need N Thing instances. In C++ that's a matter of std::vector<Thing> things(N); In python, I can use a list comprehension. things = [Thing() for _ in range(N)] However, the obvious D version doesn't work. auto things = new Thing[N]; Because Thing.init is null, this produces an array of null references. Of course, I can write a for loop to fill in the array after creation, but this feels very un-D-like. Is there a straightforward way to create a bunch of class instances?You can create separate function which fills array with instances and return it. You can make Thing a struct aliased to array of classes which again initializes properly in constructor an array. But then you should take care that struct constructor is called.
Feb 09 2013
On 02/09/2013 10:14 PM, Simon wrote:Hi, I'm new to the D programming language. Overall I'm liking things very much, but I'm still getting the hang of a few things. Here's a basic programming pattern: I have a class called Thing, and while I'm coding I decide I need N Thing instances. In C++ that's a matter of std::vector<Thing> things(N); In python, I can use a list comprehension. things = [Thing() for _ in range(N)] However, the obvious D version doesn't work. auto things = new Thing[N]; Because Thing.init is null, this produces an array of null references. Of course, I can write a for loop to fill in the array after creation, but this feels very un-D-like. Is there a straightforward way to create a bunch of class instances?Here is one way: import std.stdio; import std.range; import std.algorithm; class Thing { int i; this(int i) { this.i = i; } } void main() { auto things = iota(10).map!(i => new Thing(i))().array; } Ali -- D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html
Feb 09 2013
On 02/09/2013 10:52 PM, Ali Çehreli wrote:auto things = iota(10).map!(i => new Thing(i))().array;Actually, without the extra parentheses: auto things = iota(10).map!(i => new Thing(i)).array; Ali
Feb 09 2013
On Sunday, 10 February 2013 at 06:57:42 UTC, Ali Çehreli wrote:On 02/09/2013 10:52 PM, Ali Çehreli wrote:It's a shame there isn't any simple syntax for it, but that's some neat and flexible code. Thanks!auto things = iota(10).map!(i => new Thing(i))().array;Actually, without the extra parentheses: auto things = iota(10).map!(i => new Thing(i)).array; Ali
Feb 09 2013
On Sun, Feb 10, 2013 at 8:40 AM, Simon <none example.org> wrote:Oh, you can easily use a template: import std.array; import std.algorithm; import std.conv; import std.range; import std.stdio; class Thing { int i; this(int i) { this.i = i; } void toString(scope void delegate(const(char)[]) sink) const { sink("Thing: " ~ to!string(i)); } } /// Helper template What[] makeArray(alias What)(size_t size) { return iota(size).map!(i => new What(i)).array; } void main() { auto things = makeArray!(Thing)(10); writeln(things); }auto things = iota(10).map!(i => new Thing(i)).array; AliIt's a shame there isn't any simple syntax for it, but that's some neat and flexible code.
Feb 10 2013
On 10-2-2013 7:14, Simon wrote:Hi, I'm new to the D programming language. Overall I'm liking things very much, but I'm still getting the hang of a few things. Here's a basic programming pattern: I have a class called Thing, and while I'm coding I decide I need N Thing instances. In C++ that's a matter of std::vector<Thing> things(N); In python, I can use a list comprehension. things = [Thing() for _ in range(N)] However, the obvious D version doesn't work. auto things = new Thing[N]; Because Thing.init is null, this produces an array of null references. Of course, I can write a for loop to fill in the array after creation, but this feels very un-D-like. Is there a straightforward way to create a bunch of class instances?import std.stdio, std.algorithm; class Thing { int i; this(int i) { this.i = i; } } void main() { auto things = new Thing[10]; fill(things, new Thing(5)); foreach (t; things) writef("%d ", t.i); }
Feb 10 2013
On Sunday, 10 February 2013 at 09:48:04 UTC, Jos van Uden wrote:On 10-2-2013 7:14, Simon wrote:HELL NO!!!! What you did just right there is allocate a *single* thing _instance_ and then place 10 _references_ to that same thing in the array.Hi, I'm new to the D programming language. Overall I'm liking things very much, but I'm still getting the hang of a few things. Here's a basic programming pattern: I have a class called Thing, and while I'm coding I decide I need N Thing instances. In C++ that's a matter of std::vector<Thing> things(N); In python, I can use a list comprehension. things = [Thing() for _ in range(N)] However, the obvious D version doesn't work. auto things = new Thing[N]; Because Thing.init is null, this produces an array of null references. Of course, I can write a for loop to fill in the array after creation, but this feels very un-D-like. Is there a straightforward way to create a bunch of class instances?import std.stdio, std.algorithm; class Thing { int i; this(int i) { this.i = i; } } void main() { auto things = new Thing[10]; fill(things, new Thing(5)); foreach (t; things) writef("%d ", t.i); }
Feb 10 2013
On 02/10/2013 03:18 AM, monarch_dodra wrote:On Sunday, 10 February 2013 at 09:48:04 UTC, Jos van Uden wrote:auto things = new Thing[10]; fill(things, new Thing(5));What you did just right there is allocate a *single* thing _instance_ and then place 10 _references_ to that same thing in the array.And in case that is what we really wanted, there is the simpler but sometimes confusing array-wise syntax: auto things = new Thing[10]; things[] = new Thing(5); Ali
Feb 10 2013
On Sunday, 10 February 2013 at 06:14:37 UTC, Simon wrote:Hi, I'm new to the D programming language. Overall I'm liking things very much, but I'm still getting the hang of a few things. Here's a basic programming pattern: I have a class called Thing, and while I'm coding I decide I need N Thing instances. In C++ that's a matter of std::vector<Thing> things(N); In python, I can use a list comprehension. things = [Thing() for _ in range(N)] However, the obvious D version doesn't work. auto things = new Thing[N]; Because Thing.init is null, this produces an array of null references. Of course, I can write a for loop to fill in the array after creation, but this feels very un-D-like. Is there a straightforward way to create a bunch of class instances?The difference is that C++ will *place* the instances inside the vector. A *true* C++ equivalent would be to declare: std::vector<Thing*> things(N); As you can see, same problem. Honestly, there are a lot of fancy ways to go around the problem, but quite frankly,I think simple is best: //---- auto myThings = new Thing[](N); foreach(ref aThing; myThings) aThing = new Thing(); //----- It's not fancy, but it gets the job done. You won't confuse anyone with the code, and there is very little risk of subtle bugs (appart from forgetting the ref in the foreach loop.
Feb 10 2013