On 12/4/10 9:58 AM, Michel Fortin wrote:
On 2010-12-04 08:55:19 -0500, Andrei Alexandrescu
<[email protected]> said:
If conversion is allowed only for values (i.e. perform a memberwise
copy of one struct to another), it looks like things could work.
Almost. The problem is that that surreptitious copy completely
bypasses the constructor:
struct A(T) {
private T obj;
private bool isObject;
this(T obj_) {
obj = obj_;
static if (is(T == Object)) isObject = true;
}
}
auto a = A!Widget(new Widget);
A!Object b = a; // works, new automatic conversion rule
assert(!b.isObject); // passes, invariant is messed up
Copying a struct always bypasses the constructor, whether it's a
template or not.
That's not copying, it's moving, and it always preserves type.
If you want to maintain invariants, add the
"this(this)" postblit constructor.
The postblit constructor assumes the source and target types are the same.
Your invariant in the case above is a
little silly since it stores a value deduced from the template parameter
as a member variable. But if it's that important, fixing it is trivial:
add a postblit constructor.
this(this) {
static if (is(T == Object)) isObject = true;
else isObject = false;
}
The problem is the default and implicit behavior is broken.
I'm not sure why you imply it won't work for references. That's the
whole point of the proposal. It can work for references as long as the
memory layout is the same and each member can also be converted as a
reference.
No. For references to work with mutable objects, you need equivariance,
not contravariance. It's a classic.
Andrei