Thread overview | |||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 22, 2013 Error about @disabled constructor when there is a custom one | ||||
---|---|---|---|---|
| ||||
I have this structure: struct Scene { Array!Surface objects; // objects in the scene Array!Light lights; // lights in the scene /*private*/ BVHNode root; // root node of the BVH tree @disable this(); // disable the default constructor because space needs to be reserved for objects and lights this(size_t objectReserveSpace = 20, size_t lightReserveSpace = 3) { objects.reserve(objectReserveSpace); lights.reserve(lightReserveSpace); } } auto scene = Scene(); // error about @disabled constructor Yes, the default constructor is @disabled BUT I am not using that one. I want to use the other one - the custom constructor. I guess it signals an error because it has those defaults parameters. But shouldn't the compiler choose that one? |
January 22, 2013 Re: Error about @disabled constructor when there is a custom one | ||||
---|---|---|---|---|
| ||||
Posted in reply to Minas Mina | 22-Jan-2013 22:45, Minas Mina пишет: > I have this structure: > > struct Scene > { > Array!Surface objects; // objects in the scene > Array!Light lights; // lights in the scene > > /*private*/ BVHNode root; // root node of the BVH tree > > @disable this(); // disable the default constructor because space > needs to be reserved for objects and lights > > this(size_t objectReserveSpace = 20, size_t lightReserveSpace = 3) > { > objects.reserve(objectReserveSpace); > lights.reserve(lightReserveSpace); > } > } > > > > auto scene = Scene(); // error about @disabled constructor That is the reason I dislike D's struct constructors as they currently stand. Behold as the above is always rewritten to: auto scene = Scene.init; that is the same as Scene scene; And for Scene.init to work it has to have T.init for all of its members. You've hit what I think is the design bug w.r.t. conflating 0-argument constructor (including one with all default args) and T.init. Short answer is: use static opCall instead. In the meantime let us all pray some supreme gods so that 0-arg constructor support is introduced later on. (because opCall doesn't have some powers of constructors such as constructing const object) > Yes, the default constructor is @disabled BUT I am not using that one. I > want to use the other one - the custom constructor. I guess it signals > an error because it has those defaults parameters. But shouldn't the > compiler choose that one? The official stance seems to be that the code shouldn't compile i.e. accepts-invalid. http://d.puremagic.com/issues/show_bug.cgi?id=3438 -- Dmitry Olshansky |
January 22, 2013 Re: Error about @disabled constructor when there is a custom one | ||||
---|---|---|---|---|
| ||||
Posted in reply to Minas Mina | On 2013-01-22, 19:45, Minas Mina wrote: > I have this structure: > > struct Scene > { > Array!Surface objects; // objects in the scene > Array!Light lights; // lights in the scene > > /*private*/ BVHNode root; // root node of the BVH tree > > @disable this(); // disable the default constructor because space needs to be reserved for objects and lights > > this(size_t objectReserveSpace = 20, size_t lightReserveSpace = 3) > { > objects.reserve(objectReserveSpace); > lights.reserve(lightReserveSpace); > } > } > > > > auto scene = Scene(); // error about @disabled constructor > > Yes, the default constructor is @disabled BUT I am not using that one. I want to use the other one - the custom constructor. I guess it signals an error because it has those defaults parameters. But shouldn't the compiler choose that one? You *are* using the default one. The one without parameters *is* the default constructor, and you are calling the constructor without parameters. One could argue that the compiler should choose the other constructor, and even that having default constructors is reasonable. However, D has gone the route of not having default constructors for structs. Instead, structs are defined to be trivially constructible from T.init. The workaround is to use static opCall: struct Scene { Array!Surface objects; Array!Light lights; /*private*/ BVHNode root; @disable this(); this(size_t objectReserveSpace = 20, size_t lightReserveSpace = 3) { objects.reserve(objectReserveSpace); lights.reserve(lightReserveSpace); } static Scene opCall(size_t objectReserveSpace = 20, size_t lightReserveSpace = 3) { return Scene(objectReserveSpace, lightReserveSpace); } } -- Simen |
January 22, 2013 Re: Error about @disabled constructor when there is a custom one | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | On 01/22/2013 11:07 AM, Simen Kjaeraas wrote: > The workaround is to use static opCall: > > struct Scene > { > Array!Surface objects; > Array!Light lights; > > /*private*/ BVHNode root; > > @disable this(); That line must still be removed. > this(size_t objectReserveSpace = 20, size_t lightReserveSpace = 3) The default parameter values are not useful (or don't make sense) anymore: this(size_t objectReserveSpace, size_t lightReserveSpace) > { > objects.reserve(objectReserveSpace); > lights.reserve(lightReserveSpace); > } > > static Scene opCall(size_t objectReserveSpace = 20, size_t > lightReserveSpace = 3) > { > return Scene(objectReserveSpace, lightReserveSpace); Luckily that line calls the constructor, not itself and avoids an infinite loop. :) Ali |
January 22, 2013 Re: Error about @disabled constructor when there is a custom one | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dmitry Olshansky | From Jonathan M Davis: "...At this point, I don't think that the situation with default constructors and structs is going to change. It's a result of requiring init properties for all types, and is thus a "forced fault" in the language..." Why does requiring init properties for all types results in this? What does that even mean? |
January 22, 2013 Re: Error about @disabled constructor when there is a custom one | ||||
---|---|---|---|---|
| ||||
Posted in reply to Minas Mina | 23-Jan-2013 00:28, Minas Mina пишет: > From Jonathan M Davis: > > "...At this point, I don't think that the situation with default > constructors and > structs is going to change. It's a result of requiring init properties > for all > types, and is thus a "forced fault" in the language..." > > Why does requiring init properties for all types results in this? What > does that even mean? I don't buy it either. 0-argument constructor have nothing to do with requiring .init. -- Dmitry Olshansky |
January 22, 2013 Re: Error about @disabled constructor when there is a custom one | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dmitry Olshansky | On Tuesday, 22 January 2013 at 21:12:50 UTC, Dmitry Olshansky wrote:
> 23-Jan-2013 00:28, Minas Mina пишет:
>> From Jonathan M Davis:
>>
>> "...At this point, I don't think that the situation with default
>> constructors and
>> structs is going to change. It's a result of requiring init properties
>> for all
>> types, and is thus a "forced fault" in the language..."
>>
>> Why does requiring init properties for all types results in this? What
>> does that even mean?
>
> I don't buy it either. 0-argument constructor have nothing to do with requiring .init.
What he said.
|
January 22, 2013 Re: Error about @disabled constructor when there is a custom one | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dmitry Olshansky | On Wednesday, January 23, 2013 01:12:45 Dmitry Olshansky wrote:
> 23-Jan-2013 00:28, Minas Mina пишет:
> > From Jonathan M Davis:
> > "...At this point, I don't think that the situation with default
> > constructors and
> > structs is going to change. It's a result of requiring init properties
> > for all
> > types, and is thus a "forced fault" in the language..."
> >
> > Why does requiring init properties for all types results in this? What does that even mean?
>
> I don't buy it either. 0-argument constructor have nothing to do with requiring .init.
init prevents us from having _default_ constructors. As much as no-arg constructors are normally default constructors, they're technically separate concepts. static opCall shows us that it's perfectly possible to have no-arg constructors.
However, there's a certain danger in simply making a no-arg constructor for structs not be a default constructor, as pretty much anyone coming from another OO language will expect it to be a default constructor. For the most part, static opCall solves the problem.
- Jonathan M Davis
|
January 23, 2013 Re: Error about @disabled constructor when there is a custom one | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | On Tuesday, 22 January 2013 at 19:07:56 UTC, Simen Kjaeraas wrote: > On 2013-01-22, 19:45, Minas Mina wrote: > >> I have this structure: >> >> struct Scene >> { >> Array!Surface objects; // objects in the scene >> Array!Light lights; // lights in the scene >> >> /*private*/ BVHNode root; // root node of the BVH tree >> >> @disable this(); // disable the default constructor because space needs to be reserved for objects and lights >> >> this(size_t objectReserveSpace = 20, size_t lightReserveSpace = 3) >> { >> objects.reserve(objectReserveSpace); >> lights.reserve(lightReserveSpace); >> } >> } >> >> >> >> auto scene = Scene(); // error about @disabled constructor >> >> Yes, the default constructor is @disabled BUT I am not using that one. I want to use the other one - the custom constructor. I guess it signals an error because it has those defaults parameters. But shouldn't the compiler choose that one? > > You *are* using the default one. The one without parameters *is* the > default constructor, and you are calling the constructor without parameters. > > One could argue that the compiler should choose the other constructor, and > even that having default constructors is reasonable. However, D has gone > the route of not having default constructors for structs. Instead, > structs are defined to be trivially constructible from T.init. > Which incompatible with the desire of a NonNull construct. > The workaround is to use static opCall: > > struct Scene > { > Array!Surface objects; > Array!Light lights; > > /*private*/ BVHNode root; > > @disable this(); > > this(size_t objectReserveSpace = 20, size_t lightReserveSpace = 3) > { > objects.reserve(objectReserveSpace); > lights.reserve(lightReserveSpace); > } > > static Scene opCall(size_t objectReserveSpace = 20, size_t lightReserveSpace = 3) > { > return Scene(objectReserveSpace, lightReserveSpace); > } > } Cheap workaround as you cannot new. |
January 23, 2013 Re: Error about @disabled constructor when there is a custom one | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On 2013-45-23 04:01, deadalnix <deadalnix@gmail.com> wrote: > On Tuesday, 22 January 2013 at 19:07:56 UTC, Simen Kjaeraas wrote: >> One could argue that the compiler should choose the other constructor, and >> even that having default constructors is reasonable. However, D has gone >> the route of not having default constructors for structs. Instead, >> structs are defined to be trivially constructible from T.init. >> > > Which incompatible with the desire of a NonNull construct. Really? It's not like you cannot @disable T.init. Please show how this is a problem for NonNull!T. > Cheap workaround as you cannot new. Indeed. But it's what we've got. -- Simen |
Copyright © 1999-2021 by the D Language Foundation