Jump to page: 1 2 3
Thread overview
Error about @disabled constructor when there is a custom one
Jan 22, 2013
Minas Mina
Jan 22, 2013
Dmitry Olshansky
Jan 22, 2013
Minas Mina
Jan 22, 2013
Dmitry Olshansky
Jan 22, 2013
monarch_dodra
Jan 22, 2013
Jonathan M Davis
Jan 23, 2013
Simen Kjaeraas
Jan 22, 2013
Simen Kjaeraas
Jan 22, 2013
Ali Çehreli
Jan 23, 2013
deadalnix
Jan 23, 2013
Simen Kjaeraas
Jan 23, 2013
deadalnix
Jan 23, 2013
Simen Kjaeraas
Jan 23, 2013
deadalnix
Jan 23, 2013
Simen Kjaeraas
Jan 23, 2013
deadalnix
Jan 23, 2013
Simen Kjaeraas
Jan 23, 2013
deadalnix
Jan 23, 2013
Minas Mina
Jan 23, 2013
monarch_dodra
Jan 23, 2013
Minas Mina
January 22, 2013
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
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
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
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
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
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
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
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
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
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