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