View mode: basic / threaded / horizontal-split · Log in · Help
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
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
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
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
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
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
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
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
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
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
« First   ‹ Prev
1 2 3
Top | Discussion index | About this forum | D home