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