Post-ctor ctor

Jonathan M Davis jmdavisProg at gmx.com
Mon Aug 8 15:25:35 PDT 2011


> On 8/8/11 10:41 PM, Jonathan M Davis wrote:
> > In this particular example, what goes in initFromParameters is specific
> > to Foo anyway. So, you'd have to write it by hand regardless.
> 
> If Andrei intended his answer this way, I don't quite see how it would
> be an appropriate solution, as Andrej explicitly stated in his original
> post: »I see that as needlessly implementing in user-code what the
> compiler can already do on its own.«

Well, I don't see what the compiler could do on its own here. It'll generate 
the basic constructor which takes the struct's member variables in the order 
that they're declared, but it doesn't (and can't) generate the extra code that 
he wants which does other stuff to set those member variables, e.g.

sum = a + b + c + d;

That kind of code requires the programmer. If we had a post-constructor like 
Andrej is looking for, then he could put the code in there, but the code still 
has to go _somewhere_. The initialization of the first 4 member variables as 
happens in the example might be nice to do via traits so that the first part 
of the constructor could be generated (which would be what the compiler 
generates on its own), but the second part (the part which would go in the 
post-constructor) still has to be written by hand regardless.

So, best case, initFromParameters could use traits to generate

this.a = a;
this.b = b;
this.c = c;
this.d = d;

but the

sum = a + b + c + d;
average = (a + b + c + d) / 4;

would have to be written by hand. Honestly, I think that using a mixin here 
would be overkill. You might as well just rewrite the whole thing in each 
constructor. The real gain of something like a post constructor is in not 
having to write the first portion of the constructor. In the case where you 
have multiple constructors which need a common set of initialization code but 
which can't call a common constructor, because there's no default constructor, 
you can just use a function for that. But if you want to essentially avoid 
writing half of the constructor be letting the compiler do it for you, you 
need something like a post constructor.

Personally, I'd just write the constructor and be done with it, but I can see 
why Andrej would want something like this. If you want to do a mixin for this 
though, then you probably need to mix in the whole constructor rather than 
just the body like Andrei did. Then it can name the parameters itself, and you 
don't have the problem of having no way to query for the function parameters. 
It also avoids having to write the constructor's signature. However, unless 
you can write the mixin in a generic way which allows you to reuse it among 
structs (which would probably mean giving it a function to call which did the 
struct-specific stuff after the basic initalization), a mixin seems like total 
overkill.

So, maybe you could do something like

struct Foo
{
 int a;
 int b;
 int c;
 int d;

 int sum;
 int average;

 mixin(structInit!(4, postConstructor));

 private postConstructor()
 {
 sum = a + b + c + d;
 average = (a + b + c + d) / 4;
 }
}

and structInit would generate

this(int a, int b, int c, int d)
{
 this.a = a;
 this.b = b;
 this.c = c;
 this.d = d;
 initFunc();
}

However, that sort of template seems very writeable, and it would be 
completely reusable, so it's probably a decent solution to the problem.

- Jonathan M Davis


More information about the Digitalmars-d mailing list