resource structs and default constuction

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Mon Jun 1 12:39:31 PDT 2015


On Monday, 1 June 2015 at 19:13:46 UTC, Erik Smith wrote:
>> If you want to force that a constructor be called rather than 
>> using the init value, then you need to make the init value 
>> unusable by @disabling this(). Then the caller _has_ to 
>> explicitly call a constructor or factory function. Regardless, 
>> if you want a constructor that takes no arguments for a 
>> struct, you need a factory function, since you can't have 
>> struct constructors with no parameters.
>
> Good to know,  but disabling this() also prevents the object 
> from being a struct member, which is probably too restrictive.

It shouldn't. It should just make it so that the struct it's in 
has a @disabled init value as well - which is annoying in its own 
right, but it's not as restrictive. Regardless, if you want to 
guarantee that a struct is constructed rather than having its 
init value used, you have no choice. Asserting like you suggested 
could be done, but you'd have to put assertions in every function 
but opAssign (if you declare it) that tested whether the struct 
had been properly initialized or not, and that's going to be at 
least somewhat error-prone. If @disabling the init value is too 
restrictive though and you _can't_ use the init value, then it 
could work.

Though actually, if you can't use the init value and can't 
disable it, instead of asserting, you could always just set the 
struct to the default that you want if it's not initialized. 
That's a bit annoying, but it would be an option.

Also, based on the name of your struct - Database - it sounds 
like a handle for talking to the database, which is the sort of 
thing that I'd expect to be very long lived and for which you 
likely would only have a few actual objects allocated. And since 
you're talking about reference-counting it, clearly, you intend 
to put it on the heap. And if you're dealing with a long-lived 
object on the heap where there won't be very many of them, you 
might as well just use a class and avoid the whole 
default-constructor issue (since classes have them). Using the GC 
to allocate such objects is usually fine, and if it isn't, 
std.allocator should make allocating them easy. Having them be 
reference-counted would just increase their overhead, and what 
you're doing clearly isn't interacting well with struct semantics 
anyway, because you basically want to require that a default 
constructor be used.

>  RefCounted wouldn't be workable with this, for example.

It might not be. I don't know. I'd have to look at it. Certainly, 
if it were, it wouldn't have an init value and would have be 
explicitly initialized. But Walter and Andrei already seem to 
have come to the conclusion that RefCounted isn't going to cut it 
anyway (much as it comes close) and are looking at adding a 
ref-counting mechanism to the language, in which case, that's 
what you'd want to use rather than RefCounted for ref-counted 
objects anyway. I have no idea when that will actually be 
implemented though. Regardless, I'd suggest that you seriously 
consider using a class instead like I suggested above.

> I could still use feedback on whether the variadic create is 
> problem free.

I don't see anything wrong with it, though I'd add a template 
constraint that verified that the constructor could be called 
with the given arguments.

- Jonathan M Davis


More information about the Digitalmars-d mailing list