tail const

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Sat Dec 4 05:55:19 PST 2010


On 12/4/10 1:48 AM, Dmitry Olshansky wrote:
> On 04.12.2010 6:23, Andrei Alexandrescu wrote:
>> On 12/3/10 7:40 PM, Michel Fortin wrote:
>>> I have an idea that would fix those: make a template struct/class
>>> instance implicitly convertible to another instance of that same
>>> template if all members share the same memory layout and each member is
>>> implicitly convertible to the same member of the other template.
>>
>> I'm afraid that can't work.
>>
>> struct A(T) {
>> T obj;
>> void fun() { obj->method(); }
>> }
>>
>
> Looks discouraging at first, but perfectly valid given that the example
> works only when A!Object compiles, i.e. Object have method 'method', and
> then:
>
>> auto a = new A!Widget;
>> a.obj = new Widget;
>> A!Object b = *a; // works because Widget converts to Object
> // A!Object* b = a; // should not compile, and would be a problem if A
> is a class
> //now we have another struct b with reference to a's widget
>> b.obj = new Object; //no problem, a stays intact
>> b.fun(); // since A!Object already compiles, it's perfectly valid
>
> In fact, it looks like Michel's rule is very promising, just replace
> "struct/class" part with "struct" in definition.

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


Andrei


More information about the Digitalmars-d mailing list