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