Parameterized inheritence issues, bug or ignorance?
Joerg Joergonson via Digitalmars-d
digitalmars-d at puremagic.com
Sun Jun 19 17:34:18 PDT 2016
On Monday, 20 June 2016 at 00:15:33 UTC, David Nadlinger wrote:
> On Monday, 20 June 2016 at 00:01:58 UTC, Joerg Joergonson wrote:
>> class a { }
>> class b : a { }
>>
>> class A(T : a)
>> {
>> T x;
>> }
>>
>>
>>
>> void main(string[] argv)
>> {
>> auto y = new A!a();
>> auto z = new A!b();
>> y.x = new a();
>> z.x = new b();
>>
>>
>> auto p1 = cast(A!a)y;
>> auto p2 = cast(A!b)z;
>> auto p3 = cast(A!a)z; // Fail! Why? z.x is of type b which
>> can be down cast to type a without a problem ->
>
> As has been pointed out in dm.D.learn already (which is where
> this discussion belongs), there isn't any inheritance
> relationship between A!b and A!a.
>
> In your example, it's easy to see that there can't be if you
> ask yourself whether the purported relation should be co- or
> contravariant in nature. To put it in simple terms, if your
> cast succeeded, you could do this:
>
> ---
> p3.x = new a;
> // Now typeof(z.x) == b, but it points to an instance of a!
> ---
>
> — David
So?
auto f = 1f;
auto x = cast(int)f;
f is float, x is an int, that's what casts do when you cast
beyond their type. I mean, after all, p3.x is of type A!a and
points to the same location as something that maps to A!b. It's
no doubt going to be a problem if you stick something less in
there than you were suppose do.
If the point is: Too keep programmers from making mistakes. Then
that's fine. But that doesn't mean in all cases is is bad.
Sure I can down cast to a ButtonItem then store ButtonItem's in
something that's actually a SliderItem, which is effectively
upcasting behind the scenes... But that's my fault. It can be
done outside inheritance too. Take a pointer to an float and
write an int value to it... Same problem.
If this is a restriction, then fine. Then the question is, how to
get around it. I don't do anything that causes problem. I only
iterate over the base type and never assign a base type to
something that might contain a derived type.
Can I just force the cast in some way if I know good an well it
works for ever? Or do I have to write extra code to get around
axiom: "We did this to save you trouble because we know better
than you what you are doing. Go forth and write more code!"?
More information about the Digitalmars-d
mailing list