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