Error about @disabled constructor when there is a custom one

monarch_dodra monarchdodra at gmail.com
Wed Jan 23 04:07:47 PST 2013


On Wednesday, 23 January 2013 at 11:03:45 UTC, Minas Mina wrote:
> Why is it required to have the .init property? Where is it 
> useful and why was this decision made?

.init is very useful in the sense that it represents the raw 
object, *statically*.

This is useful for declaring statics.

It also makes constructors straightforward, in a simple 2 pass 
scheme (copy T.init, then run constructor).

More importantly, the T.init state is also the one you are 
supposed to have post destruction (Or at least, calling a 
destructor on T.init is supposed to be safe). This allows for 
some *very* efficient and built-in move semantics:

To move a into b, simply destroy b, memcopy a into b, memcopy 
T.init over a.

Notice how massively simpler this is compared to C++'s explicit 
Rvalue references? I *dare* you to try doing that with C++.

"DEFAULT" constructor breaks this entire scheme, as it implies 
that T.init is not an object's natural state. It jeopardizes a 
static destructible state.

The problem is that this overlaps with having an "explicit 
constructor that takes no arguments". This is particularly 
problematic for objects that have pointers to payloads that 
represent "shallow" objects. AA's is a prime example of this:

//----
     void insert5(int[int] i)
     {
         i[5] = 5;
     }

     int[int] a;           //Un-initialized T.init state
     int[int] b = [1 : 1]; //initialized
     int[int] c = [1 : 1]; c.remove(1); //Empty but initialized
     insert5(a);
     insert5(b);
     insert5(c);
     assert(a is null);           //Oh no!
     assert(b == [1 : 1, 5 : 5]); //5 correctly appended
     assert(c == [5 : 5]);        //5 correctly copied
//----

In this example, I had to jump through loops to initialize c.


More information about the Digitalmars-d mailing list