| Thread overview | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 07, 2011 Post-ctor ctor | ||||
|---|---|---|---|---|
| ||||
Just throwing an idea..
structs are great since you don't have to make a special constructor just to initialize its fields. E.g.:
struct Foo
{
int a;
int b;
int c;
int d;
}
void main()
{
auto foo = Foo(1, 2, 3, 4);
}
But what if I add an extra couple of fields that have to be initialized based on only the first 4 fields, and I still want to keep the same call in the user code? Here's a hypothetical case:
struct Foo
{
int a;
int b;
int c;
int d;
int sum;
int average;
post this() // post-ctor ctor
{
sum = a + b + c + d;
average = (a + b + c + d) / 4;
}
}
void main()
{
auto foo = Foo(1, 2, 3, 4);
}
A post-construction ctor would do any final initializations after field initialization, or after a call to a custom ctor. Otherwise I would have to write:
struct Foo
{
int a;
int b;
int c;
int d;
int sum;
int average;
this(int a, int b, int c, int d)
{
this.a = a;
this.b = b;
this.c = c;
this.d = d;
postCtor();
}
private void postCtor()
{
sum = a + b + c + d;
average = (a + b + c + d) / 4;
}
}
void main()
{
auto foo = Foo(1, 2, 3, 4);
}
I see that as needlessly implementing in user-code what the compiler can already do on its own. If we had a post-ctor ctor, partial initialization could be done via field initialization instead of using a hand-written ctor, and then a post-ctor would initialize the rest of the fields.
Good idea / bad idea?
I have a feeling this would clash with that "can't have a default ctor on a struct" rule. I just hate having to manually write ctors for cases where the first N fields are initialized in order while the rest need special initialization.
| ||||
August 07, 2011 Re: Post-ctor ctor | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | Andrej Mitrovic: > Good idea / bad idea? I prefer a solution that to me looks simpler, discussed a bit here: http://d.puremagic.com/issues/show_bug.cgi?id=3878 With that idea your struct becomes: struct Foo { int a, b, c, d, sum, average; this(int this.a, int this.b, int this.c, int this.d) { sum = a + b + c + d; average = (a + b + c + d) / 4; } } Bye, bearophile | |||
August 07, 2011 Re: Post-ctor ctor | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | > With that idea your struct becomes:
Or just:
struct Foo {
int a, b, c, d, sum, average;
this(this.a, this.b, this.c, this.d) {
sum = a + b + c + d;
average = (a + b + c + d) / 4;
}
}
Bye,
bearophile
| |||
August 07, 2011 Re: Post-ctor ctor | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | > this(int this.a, int this.b, int this.c, int this.d) {
> sum = a + b + c + d;
> average = (a + b + c + d) / 4;
> }
Can't express how awkward this is.
| |||
August 07, 2011 Re: Post-ctor ctor | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Trass3r | Trass3r:
> > this(int this.a, int this.b, int this.c, int this.d) {
> > sum = a + b + c + d;
> > average = (a + b + c + d) / 4;
> > }
>
> Can't express how awkward this is.
Why don't you try to express how awkward it is?
Well, code like this is shorter than what the OP has suggested, it's DRY, it's probably easy to understand (I think you don't need to go look into D docs every time you see something like this), it's easy to type, it avoids a common bug in my code (caused by mixing fields and arguments in the constructor):
this(this.a, this.b, this.c, this.d) {
sum = a + b + c + d;
average = (a + b + c + d) / 4;
}
Bye,
bearophile
| |||
August 08, 2011 Re: Post-ctor ctor | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On 8/7/11 1:16 PM, Andrej Mitrovic wrote:
> Just throwing an idea..
>
> structs are great since you don't have to make a special constructor
> just to initialize its fields. E.g.:
>
> struct Foo
> {
> int a;
> int b;
> int c;
> int d;
> }
>
> void main()
> {
> auto foo = Foo(1, 2, 3, 4);
> }
>
> But what if I add an extra couple of fields that have to be
> initialized based on only the first 4 fields, and I still want to keep
> the same call in the user code?
Just define a mixin and use it:
this(int a, int b, int c, int d) {
mixin(initFromParameters());
...
}
A similar macro could help assignments.
Andrei
| |||
August 08, 2011 Re: Post-ctor ctor | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Andrei Alexandrescu:
> this(int a, int b, int c, int d) {
> mixin(initFromParameters());
> ...
> }
>
> A similar macro could help assignments.
Do you see people using that in real code?
Bye,
bearophile
| |||
August 08, 2011 Re: Post-ctor ctor | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 8/8/11 1:59 PM, bearophile wrote:
> Andrei Alexandrescu:
>
>> this(int a, int b, int c, int d) {
>> mixin(initFromParameters());
>> ...
>> }
>>
>> A similar macro could help assignments.
>
> Do you see people using that in real code?
Yes.
Andrei
| |||
August 08, 2011 Re: Post-ctor ctor | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 8/8/11 6:08 AM, Andrei Alexandrescu wrote:
> On 8/7/11 1:16 PM, Andrej Mitrovic wrote:
>> struct Foo
>> {
>> int a;
>> int b;
>> int c;
>> int d;
>> }
> Just define a mixin and use it:
>
> this(int a, int b, int c, int d) {
> mixin(initFromParameters());
> ...
> }
There is currently no »legal« way to get the parameter names in D (other than parsing the .stringof output for the function type, which is not guaranteed to work, as far as I know), so I don't see how this could be implemented. Did I miss something obvious?
David
| |||
August 08, 2011 Re: Post-ctor ctor | ||||
|---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | David Nadlinger wrote:
> On 8/8/11 6:08 AM, Andrei Alexandrescu wrote:
>> On 8/7/11 1:16 PM, Andrej Mitrovic wrote:
>>> struct Foo
>>> {
>>> int a;
>>> int b;
>>> int c;
>>> int d;
>>> }
>> Just define a mixin and use it:
>>
>> this(int a, int b, int c, int d) {
>> mixin(initFromParameters());
>> ...
>> }
>
> There is currently no »legal« way to get the parameter names in D (other than parsing the .stringof output for the function type, which is not guaranteed to work, as far as I know), so I don't see how this could be implemented. Did I miss something obvious?
>
> David
Always use structs and classes with exactly 4 fields and always name them (as well as the constructor arguments) a,b,c,d.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply