tail const

Michel Fortin michel.fortin at michelf.com
Sat Dec 4 04:13:30 PST 2010


On 2010-12-04 02:48:26 -0500, Dmitry Olshansky <dmitry.olsh at gmail.com> said:

> 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.

Yes, indeed. I was a little over-enthusiastic when saying it'd work for 
classes too; the vtable pointer would be a problem for that. But it 
seems it can work well for structs.

You're right, "A!Object b = a" should compile fine while "A!Object* b = 
&a;" should not, because it'd allow you to assign any Object to the 
Widget field. That said, you can still allow this convertion: 
"A!(const(Object))* b = &a;". That's because the obj member becomes 
const and you can no longer assign anything to it.

So, to refine the rules I'd say a templated struct can be converted to 
a lvalue of another instance of the same templated struct with the same 
memory layout if all members can be converted to a lvalue of their type 
in the second struct. If one field can only be converted as a rvalue, 
the result is a rvalue struct. We should also make it so Widget can 
convert to const(Object) as an lvalue; that doesn't work currently.


-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/



More information about the Digitalmars-d mailing list