D casting broke?

Joerg Joergonson via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Jun 20 19:45:45 PDT 2016


On Monday, 20 June 2016 at 23:35:28 UTC, Steven Schveighoffer 
wrote:
> On 6/19/16 5:19 PM, Joerg Joergonson wrote:
>> On Sunday, 19 June 2016 at 20:21:35 UTC, ag0aep6g wrote:
>>> On 06/19/2016 09:59 PM, Joerg Joergonson wrote:
>>>> This should be completely valid since B!T' obviously derives 
>>>> from A!T
>>>> directly
>>>
>>> ok
>>>
>>>> and we see that T' derives from b which derives from a
>>>> directly.
>>>
>>> ok
>>>
>>>> So B!b is an entirely derived from A!a
>>>
>>> No. B!b is derived from A!b, not from A!a. `b` being derived 
>>> from `a`
>>> does not make A!b derived from A!a.
>>
>> why not? This doesn't seem logical!
>
> Because:
>
> class A(T : a)
> {
>   static if(is(T == a))
>      int oops;
>   ...
> }
>
> Now A!b and A!a have different layouts. They cannot be related, 
> even if the template arguments are related. I could introduce 
> another virtual function inside the static if, same result -- 
> vtable is messed up.
>
> In general, an instantiation of a template aggregate (class or 
> struct) is not castable implicitly to another instantiation of 
> the same aggregate unless explicitly declared.
>
> And note that D does not allow multiple inheritance. I don't 
> think you can solve this problem in D.
>
> -Steve

Yes, but all you guys are doing is leaving out what I'm actually 
doing and creating a different problem that may not have the same 
issues.

I have this:

(Button!ButtonItem) : (Slider!SliderItem)


In my code/design that is different than

Button!ButtonItem : Button!SliderItem : Slider!SliderItem

The middle case, the case you guys are reducing do, never occurs. 
I never have that problem because I never *mix* a Button with a 
SliderItem. It makes no sense in my design. Hence I don't have to 
worry about that case, but that is the case you guys keep 
bringing up.

A SliderItem adds info to a ButtonItem that makes it "slider 
like". In my case, A slide amount. This field is useless to use 
in a Button. It is only used by the Slider class(In fact, only by 
SliderItem).

I realize that if one did a cast of a Button!SliderItem down to a 
Button!ButtonItem, things can become problematic. This doesn't 
occur in my design.

I see it more like


[Button!ButtonItem]
        |
        v
[Slider!SliderItem]


rather than


Button!ButtonItem
            |
            v
Button!SliderItem
    |
    v
Slider!SliderItem


or

Button!ButtonItem
    |
    v
Slider!ButtonItem
            |
            v
Slider!SliderItem


The first has the problem casting Button!SliderItem to 
Button!ButtonItem. (Same as List!mystring to List!string)

The second has the problem Slider!SliderItem to Slider!ButtonItem 
(It's the same problem in both)


There seems to be three relationships going on and D does one.

Let != not related(not derived from)
For a and b

a != b. D's assumption, never safe
a -> b works some of the time depending on usage
a = b works all the time

But it is more complex with A!a and B!b

A != B and a != b. never safe to cast in any combination
A != B and a = b. never safe to cast
A != B and a -> b. never safe to cast
A -> B and a != b. never safe to cast
A = B and a != b. never safe to cast
A -> B and a -> b. Sometimes safe to cast
A -> B and a = b. Sometimes safe to cast
A = B and a = b. Always safe to cast

Things get "safer" to cast as the relationships between the types 
becomes more "exact".  D always assumes worst case for the 
template parameters.

Some designs, though, work in the A -> B and a -> b 'region' with 
the fact that A!b never occurs, which as been shown is 
problematic through out this thread(but it is really just an 
extension of the first case because both are derivation from A 
and it really adds nothing to the complexity).
































More information about the Digitalmars-d-learn mailing list