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






























Reply via email to