struct inheritance

Don Clugston dac at nospam.com.au
Mon Sep 3 02:42:35 PDT 2007


kris wrote:
> Bill Baxter wrote:
>> Regan Heath wrote:
>>> kris wrote:
>>>> Bill Baxter wrote:
>>>>> Robert Fraser wrote:
>>>>>> Bill Baxter Wrote:
>>>>>>
>>>>>>> Let us all turn our copies of WalterAndrei.pdf to page 40 where 
>>>>>>> yea verily it doth say:
>>>>>>>
>>>>>>>      struct M { int a; }
>>>>>>>      struct S {
>>>>>>>         M m;
>>>>>>>         alias m this;
>>>>>>>         int b;
>>>>>>>      }
>>>>>>>
>>>>>>> Why not just allow mixin to do this?
>>>>>>>
>>>>>>>      struct M { int a; }
>>>>>>>      struct S {
>>>>>>>         mixin M;
>>>>>>>         int b;
>>>>>>>      }
>>>>>>>
>>>>>>> That's basically the way it's done now except now it would be 
>>>>>>> more like:
>>>>>>> template MMixin() { int a; }
>>>>>>> struct M { mixin M; }
>>>>>>> struct S { mixin M; int b; }
>>>>>>>
>>>>>>> Just let us treat a struct like a zero arg template for mixin 
>>>>>>> purposes.
>>>>>>>
>>>>>>> --bb
>>>>>>
>>>>>> It amounts to the same thing, so it just depends on which syntax 
>>>>>> you prefer. Personally, I like...
>>>>>>
>>>>>> struct S : M { int b; }
>>>>>>
>>>>>> ... meaning S is non-polymorphically inherited from M. I guess the 
>>>>>> argument against taht syntax was that it would be confusing for 
>>>>>> people from a C++ background who assume polymorphic inheritance 
>>>>>> for structs.
>>>>>>
>>>>>> Anyways, it's up to Walter to decide on the syntax, and he says 
>>>>>> "alias this".
>>>>>
>>>>> I did just think of one issue which is that constructors/opCalls 
>>>>> for M would be weird.  S needs to decide how to initialize the M 
>>>>> part, which would be difficult if M's constructors are just mixed 
>>>>> in directly.
>>>>>
>>>>> I guess from a compiler-writers perspective "alias this" is more 
>>>>> like what actually happens when you inherit in typical C++ 
>>>>> fashion.  In that case I guess I'd prefer 'import'
>>>>>
>>>>>       struct M { int a; }
>>>>>       struct S {
>>>>>          import M;
>>>>>          int b;
>>>>>       }
>>>>>
>>>>> then you can specify when you need to access the M parts just like 
>>>>> you do in C++ by M.member.
>>>>>
>>>>> I'd even prefer "alias m .;" to "alias m this;".  It just seems 
>>>>> wrong and goes against the nice happy view that 'this' is just an 
>>>>> implicitly defined pointer member.
>>>>>
>>>>> --bb
>>>>
>>>> Perhaps a bigger problem is this:
>>>>
>>>> #       struct M { int a; }
>>>> #       struct S {
>>>> #          int b;
>>>> #          import M;
>>>> #       }
>>>>
>>>> Now, S is no longer derived from M. Hence, it would seem the right 
>>>> way to do this is to take it out of the hands of the developer and 
>>>> do something akin to
>>>>
>>>> #    struct S : M
>>>>
>>>> as had been suggested previously. Sure, that particular syntax may 
>>>> mean something else to some C++ folks, but at least the intent is 
>>>> clear and the /outcome/ is consistent.
>>>
>>> When you say "derived from M" are you referring to the 
>>> ordering/layout of M matching that of the start of S (new fields of S 
>>> therefore existing in the part of S which is larger than M).
>>>
>>> I'm not sure "derived" is the right term to use, we don't want to 
>>> confuse it with class derivation, perhaps saying "S is based on M" is 
>>> better?  /You say potatoes I say ../
>>>
>>> As one of the main reasons/uses for structs is to define a specific 
>>> layout in memory, perhaps the main reason for Walters syntax is to 
>>> make it possible to define that layout however required.
>>
>> Another good use for structs is for traits class with little or no 
>> data.  Mostly just a collection of types and static functions.  Having 
>> the ability to extend these structs is handy.  A library can define a 
>> set of base types A, and users can add to or modify it without having 
>> to know all the stuff that was in A to begin with.  Or vice versa, I 
>> define the base and pass that to the library and the library adds a 
>> few more things to it.
>>
>> The reason these should be structs is because sometimes you want to 
>> add in maybe one or two small data members that control operation.  
>> For instance you might have a 'compare' function in the traits and 
>> want to parameterize it by a data member to act like either less-than 
>> or greater-than.  Such things should have value semantics.
>>
>> --bb
> 
> 
> Another principal use it to enclose an opApply() with some relevant 
> context. Returning such things by value to a foreach() is one of the 
> coolest things about D

Looking forward to your next talk "foreach fo' Shizzle". <g>



More information about the Digitalmars-d mailing list