tail const
Michel Fortin
michel.fortin at michelf.com
Sat Dec 4 04:22:41 PST 2010
On 2010-12-04 07:13:30 -0500, Michel Fortin <michel.fortin at michelf.com> said:
> 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.
That wasn't very well put. Here I was looking only at the obj field. As
defined above it wouldn't compile because "fun() { obj.method() }"
won't compile for Object and the template won't instanciate. Please
ignore "fun()" when reading all this.
> 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