Templated class defaults and inheritence

Joerg Joergonson via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Jun 18 09:08:31 PDT 2016


On Saturday, 18 June 2016 at 12:15:56 UTC, Klaus Kalsesh wrote:
> On Saturday, 18 June 2016 at 02:11:23 UTC, Joerg Joergonson 
> wrote:
>> I have something like
>>
>> class X;
>> class subfoo : X;
>> class subbaz : X;
>>
>> class foo : X
>> {
>>     subfoo bar;
>> }
>>
>> class baz : X;
>>
>>
>> which I have modified so that
>>
>> class subbaz : subfoo;
>> class baz : foo;
>>
>> (essentially baz is now a derivation of foo while before it 
>> was of X)
>>
>> the problem is that subbaz uses subfoo bar; when it also needs 
>> to use a derived type. (so it is a full derivation of foo and 
>> subfoo)
>>
>>
>> To accomplish that I parameterized foo so I can do
>>
>> class foo!T : X
>> {
>>     T bar;
>> }
>>
>>
>> and I can now do
>>
>> class baz : foo!subbaz;
>>
>>
>> There are two problems with this though:
>>
>>
>> 1. How can I create a default foo!(T = subfoo) so I can just 
>> instantiate classes like new foo() and it is the same as 
>> foo!subfoo()? I tried creating a class like class foo : 
>> foo!subfoo; but I get a collision. I guess an alias will work 
>> here just fine though?(just thought of it)
>
> You must declare an alias:
>
> alias FooSubfoo = foo!subfoo;
> FooSubfoo fsf = new FooSubfoo;
>
>
No, this is not what I'm asking

I would want something like

alias foo = foo!subfoo;

Not sure, though, if a when I instantiate like

new foo();

If the compiler will understand it is new foo!subfoo(); I see no 
problem here but haven't tested it.



>> 2. The real problem is that baz isn't really a true derivation 
>> of foo like it should be. foo!subfoo and foo!subbaz are 
>> different types. I want the compiler to realize that 
>> foo!subbaz(and hence baz) is really a derived foo!subfoo and 
>> ultimately X.
>
> For multiple inheritence in classes, the standard way of doing 
> is with interfaces.
>

This is not multiple inheritance and alias this won't work.

Let me explain better:

X -> foo%subfoo
   -> baz%subbaz

by -> I mean inherits and by %, I mean "uses"(say, as a field or 
method parameter or whatever)

This then says that foo uses subfoo and is derived from X. 
Similarly for baz.

These are two distinct types(hence the two different lines)

Now, if baz inherits from foo instead of X, we have

X -> foo%subfoo -> baz%subfoo

But if subfoo -> subbaz, then we should be able to do

X -> foo%subfoo -> (baz%subfoo) -> baz%subbaz.

Note the are now on the same line. baz%subbaz is a derived type 
of foo%subfoo, not just X as in the first two line case.

This is an important distinction in the type system.


It's sort of multiple inheritance in that multiple types are used 
but each type only inherits once.

In C# we have the "where" keyword that lets us tell the compiler 
something like "where subbaz inherits from subfoo".



Dlang once had a page that had ways to express stuff like this 
but I can no longer find it ;/

It might be a syntax like

class baz!T : foo!(T : subfoo);

which may say "T must be derived from subfoo". Then baz!subbaz 
would work and it would be a derived type of foo!subfoo(rather 
than just X).








More information about the Digitalmars-d-learn mailing list