Topic: inherited" revisited


Author: bs@alice.att.com (Bjarne Stroustrup)
Date: 10 Jun 94 23:52:04 GMT
Raw View


hugp@actrix.gen.nz (Peter Hug @ Actrix Information Exchange) writes

 > In article <770908684.10608@minster.york.ac.uk> <mhw@minster.york.ac.uk> wrote:
 > > I think C++ has got big enough that arguments about avoiding a bloated
 > > language start to seem a little leaky. How about overloading the inherited
 > > keyword to allow its use as a storage class modifier, and removing the
 > > `class X : ....' stuff from the language. For example:
 > >
 > [sample code deleted]

 > I am amazed that the only argument against the inherited keyword is the
 > ambiguity it causes when used with MI.

Hmmm. Maybe parts of this discussion didn't reach New Zealand?
The ``ambiguity with  MI'' argument is bogus.
See ``The Design and Evolution of C++'' for the real reasons.

 > I have so far failed to find MI
 > useful. I would find it more appropriate if members of a class could be
 > exposed to a certain audience. Then my DateTime class (which has a Date
 > and a Time object as instance members) would not require to replicate all
 > methods from the Date and the Time class. It simply declare these members
 > such that their interface is availabvle to DateTime clients also.

Maybe this isn't quite what you meant, but consider:

 class DateTime : public Date, public Time { };

 f(const Date&);
 g(const Time&);

 void h(const DateTime& dt)
 {
  f(dt);
  g(dt);
 }

This is hard to achieve if you start out with

 class DateTime {
  Date d;
  Time t;
  // ...
 };




Author: hugp@actrix.gen.nz (Peter Hug)
Date: Wed, 8 Jun 1994 21:40:25 GMT
Raw View
In article <770908684.10608@minster.york.ac.uk>,
 <mhw@minster.york.ac.uk> wrote:
> I think C++ has got big enough that arguments about avoiding a bloated
> language start to seem a little leaky. How about overloading the inherited
> keyword to allow its use as a storage class modifier, and removing the
> `class X : ....' stuff from the language. For example:
>
[sample code deleted]

I am amazed that the only argument against the inherited keyword is the
ambiguity it causes when used with MI. I have so far failed to find MI
useful. I would find it more appropriate if members of a class could be
exposed to a certain audience. Then my DateTime class (which has a Date
and a Time object as instance members) would not require to replicate all
methods from the Date and the Time class. It simply declare these members
such that their interface is availabvle to DateTime clients also.

--
Peter Hug             |                               |  Lieber
Maxi Solutions Ltd    |   Voice: (+64) 4 298 3441     |  arm dran
Paraparaumu Beach     |   Fax:   (+64) 4 297 2288     |  als
New Zealand           |   email: hugp@actrix.gen.nz   |  arm ab




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Thu, 9 Jun 1994 02:31:23 GMT
Raw View
In article <Cr3LJE.7un@actrix.gen.nz> hugp@actrix.gen.nz (Peter Hug) writes:
>In article <770908684.10608@minster.york.ac.uk>,
> <mhw@minster.york.ac.uk> wrote:
>> I think C++ has got big enough that arguments about avoiding a bloated
>> language start to seem a little leaky. How about overloading the inherited
>> keyword to allow its use as a storage class modifier, and removing the
>> `class X : ....' stuff from the language. For example:
>>
>[sample code deleted]
>
>I am amazed that the only argument against the inherited keyword is the
>ambiguity it causes when used with MI.

 The argument is really that it is not useful enough to extend
the language. If we added inherited I can think of 200 much more useful
extensions. I've never needed "inherited" and cant conceive of
how it could be used correctly. :-)

>I have so far failed to find MI useful.

 I've failed to find many situations where MI isnt
potentially useful: those situations most people think MI is
not useful are usually design errors :-)

 In particular, if A and B and C are concepts
represented by a abstract classes, then A+B and B+C and C+A
and A+B+C seem to be sensible aggregations.

 In fact, I have found exactly the opposite:
SI is almost uselss in that it should be used only ONCE,
deriving a representation of a concept. (Concrete  : Abstract)

 OK, I'm being extreme :-)

>I would find it more appropriate if members of a class could be
>exposed to a certain audience. Then my DateTime class (which has a Date
>and a Time object as instance members) would not require to replicate all
>methods from the Date and the Time class. It simply declare these members
>such that their interface is availabvle to DateTime clients also.

 But they ARE!

 class DateTime {
 public:
  Date d;
  Time t;
 } dt;

 dt.d.method();
 dt.t.method();

no problem. :-)
--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA




Author: mhw@minster.york.ac.uk
Date: 6 Jun 1994 13:18:04 GMT
Raw View
In article <BWH.94May31230858@beach.cis.ufl.edu>,
Brian Hook <bwh@beach.cis.ufl.edu> wrote:
>In article <Cqos5J.95y@actrix.gen.nz> hugp@actrix.gen.nz (Peter Hug) writes:
>>   IMHO it is one of the issues swept under the carpet by the language
>>   designers. Practitioners are often given examples of how to bypass certain
>>   shortcommings of the language. However, these *fixes* are never quite
>>   satisfactory. The _inherited_ typdef with class scope is just another of
>>   these dirty fixes. Yea, I want a *inherited* keyword too!
>
>Well, I doubt it was "swept under the carpet" by the language designers,
>but from what I hear it seems very unlikely to be seriously considered.
>The (widely known) problem is that everyone has some specific feature or
>keyword or what not that would make their life oh so much better -- and you
>get a language that is way too bloated if all of these are approved.

I think C++ has got big enough that arguments about avoiding a bloated
language start to seem a little leaky. How about overloading the inherited
keyword to allow its use as a storage class modifier, and removing the
`class X : ....' stuff from the language. For example:

class D : public B {
 ...
};

could be replaced by

struct D {
private:
 ...
public:
 inherited B;
 ...
};

which (to me) more closely represents the storage aggregation and
name space composition which inheritance in C++ represents.

I'm not seriously suggesting that `class' and the inheritance notation
should be removed at this stage in the game, but if they didn't exist
there are work arounds and alternatives which (I think) are simpler.
What makes these more useful syntactic short cuts than `inherited'?

-Mark.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Mark H. Wilkinson <mhw@minster.york.ac.uk>  : Research student in user
University of York, England                 : interface management systems




Author: bwh@beach.cis.ufl.edu (Brian Hook)
Date: 30 May 1994 13:02:15 GMT
Raw View
I know I know, this has been gone over a million times (in various flame
wars on comp.lang.c++), but no conclusion has ever really been drawn to my
satisfaction.  It seems that the odds (this is only hearsay, as I'm not a
committee member) of introducing an "super" or "inherited" or "derived"
keyword are pretty slim.

I personally would really like such a capability, and I'm sure many others
that program in a certain "delegate work to derived classes" style would
find it a benefit.  As far as I know, here are the various arguments for
and against introduction of such a keyword:

(Oh, for those that don't know what I'm referring to, it would involve the
introduction of a new keyword that is automatically set to the parent's
class type, i.e. class A -> class B, B::foo() { inherited::foo(); } would
call A::foo() )

1.  Such a keyword isn't necessary because you can do it manually:

class foo : public bar
{
   typedef bar inherited;
};

My answer to this is that it's very error prone, e.g. what happens when you
introduce a new class in between bar and foo?  Your code will mysteriously
break.  Another problem I have with this is that different libraries will
possibly use different words -- I know "inherited" and "super" are very
popular.  Also, it's just a plain nuisance having to define it everywhere,
and sometimes screwing up (typing the wrong class name), and sometimes
forgetting and having to go back.

And yes, I know, "everyone wants their own extension" and "everyone pays
lip service to stability and simplicity", however this is a specific
language feature that would probably save a lot of time and effort for a
lot of developers, and allow for a generally cleaner coding style for those
who do a lot of work with "inherited" or "super" type keywords.

2.  Such a keyword is ambiguous under MI.

No different than if the typedef were used, and no different if you called
"foo()" that existed in two parent classes.  In other words, this would
require (like any other time such ambiguity arose) an explicit
qualification.

3.  Potential conflict with existing variables, typedefs, of the same name.

Big deal...new keywords always cause this problem.  Add a compiler switch
on newer compilers to defeat this.

Any comments?

Thanks,

Brian
--
+-----------------------------------------------------------------+
| Brian Hook            | Specializing in real-time 3D graphics   |
| Box 90315             |-----------------------------------------|
| Gainesville, FL 32607 | Internet: bwh@cis.ufl.edu | Free Tibet! |
+-----------------------------------------------------------------+




Author: tong@si.tn.tudelft.nl (Bart van Tongeren)
Date: Mon, 30 May 1994 16:58:08 GMT
Raw View
In article 94May30090215@beach.cis.ufl.edu, bwh@beach.cis.ufl.edu (Brian Hook) writes:

]1.  Such a keyword isn't necessary because you can do it manually:
]
]class foo : public bar
]{
]   typedef bar inherited;
]};
]
]My answer to this is that it's very error prone, e.g. what happens when you
]introduce a new class in between bar and foo?  Your code will mysteriously
]break.

I prefer another name to denote the base class scope:

 class foo : public bar {
     typedef bar base;
 public:
     // ...
 };

You won't forget to change the typedef if you change 'public bar'.
(If you do, this will probably be not your only problem..)

]2.  Such a keyword is ambiguous under MI.
]
]No different than if the typedef were used,

Indeed, no advantage for a new keyword here.

]3.  Potential conflict with existing variables, typedefs, of the same name.

Indeed, no advantage for a new keyword here.

---
* Bart van Tongeren ----- Delft University of Technology, Netherlands *
| Quantitative Analysis of Spin Imaging Signals - Applied Physics Lab |
| email tong@si.tn.tudelft.nl  voice +31-15-784059  fax +31-15-624978 |
*_____________________________ - = * = - _____________________________*





Author: mikey@mcs.com (Mike Young)
Date: Mon, 30 May 1994 15:35:14
Raw View
In article <BWH.94May30090215@beach.cis.ufl.edu> bwh@beach.cis.ufl.edu (Brian Hook) writes:

>1.  Such a keyword isn't necessary because you can do it manually:

>class foo : public bar
>{
>   typedef bar inherited;
>};

>My answer to this is that it's very error prone, e.g. what happens when you
>introduce a new class in between bar and foo?  Your code will mysteriously
>break.

How would it react with the keyword? It would break, too, in exactly the same
way unless it did something very counter-intuitive.

> Another problem I have with this is that different libraries will
>possibly use different words -- I know "inherited" and "super" are very
>popular.

Shouldn't be a problem. The typedef should be private. "inherited" outside the
class scope should be meaningless.

>  Also, it's just a plain nuisance having to define it everywhere,
>and sometimes screwing up (typing the wrong class name), and sometimes
>forgetting and having to go back.

Yes. This is a good reason, but is it a compelling reason? I don't use it
enough to warrant a flame.

>2.  Such a keyword is ambiguous under MI.

>No different than if the typedef were used, and no different if you called
>"foo()" that existed in two parent classes.  In other words, this would
>require (like any other time such ambiguity arose) an explicit
>qualification.

Disambiguate using a typedef, perhaps? Or do you mean something like:
  inherited::Base1::foo( );
  inherited::Base2::bar( );

Or possibly the error prone equivalent of:
  typedef Base1 inherited1;
  typedef Base2 inherited2;

I'm curious how you would "qualify" the keyword without negating its
usefulness. The current case would be:
  typedef Base1 inherited;
   ...
  inherited::foo();
  Base2::bar();


>3.  Potential conflict with existing variables, typedefs, of the same name.

>Big deal...new keywords always cause this problem.  Add a compiler switch
>on newer compilers to defeat this.

It **IS** a big deal. I think that was their conclusion.

Mike.




Author: bwh@beach.cis.ufl.edu (Brian Hook)
Date: 30 May 1994 22:43:25 GMT
Raw View
In article <mikey.42.000F96D8@mcs.com> mikey@mcs.com (Mike Young) writes:

>How would it react with the keyword? It would break, too, in exactly the same
>way unless it did something very counter-intuitive.

Not at all.  Existing code would work just fine.  Introducing a new
class in a hierarchy doesn't necessarily mean you have to go through
and change all of the existing classes that inherit from -- a keyword
would handle this at the next recompile.

   > Another problem I have with this is that different libraries will
   >possibly use different words -- I know "inherited" and "super" are very
   >popular.

>Shouldn't be a problem. The typedef should be private. "inherited" outside
>the class scope should be meaningless.

Yes, but when using multiple libraries things will be inconsistent.  Once
again, a nuisance only.

   >  Also, it's just a plain nuisance having to define it everywhere,
   >and sometimes screwing up (typing the wrong class name), and sometimes
   >forgetting and having to go back.

>   Yes. This is a good reason, but is it a compelling reason? I don't use it
>   enough to warrant a flame.

That's my question -- are enough nuisances that are somewhat solvable by
a new keyword enough to get a new keyword in?  I didn't mean to flame,
and my post was not a flame -- I wanted to see what the rationale/beliefs
behind not wanting a new keyword "inherited" added were.  The stuff in
D&E left me a little hungry for more, that's all.

   >2.  Such a keyword is ambiguous under MI.

   >No different than if the typedef were used, and no different if you called
   >"foo()" that existed in two parent classes.  In other words, this would
   >require (like any other time such ambiguity arose) an explicit
   >qualification.

>   Disambiguate using a typedef, perhaps? Or do you mean something like:
>     inherited::Base1::foo( );
>     inherited::Base2::bar( );

No...

>   Or possibly the error prone equivalent of:
>     typedef Base1 inherited1;
>     typedef Base2 inherited2;

No...

>   I'm curious how you would "qualify" the keyword without negating its
>   usefulness. The current case would be:
>     typedef Base1 inherited;
      ...
>     inherited::foo();
>     Base2::bar();

And no...That's one of the primary hurdles for it.  A lot of libraries
don't use MI, and so this isn't a problem.  Actually, I'm curious how
many libraries out there DO use MI, especially MI in the context of
delegating functionality to derived classes.  In other words, when
MI is used, will "inherited" be used also?

I don't know, I don't use MI enough, nor have I done enough in depth
research of existing large scale foundation libraries, to start
patterning the usage of "inherited" type devices in the context of
of MI.

But, to answer, basically "inherited" is nullified under MI when
ambiguity arises.  This is just a fact of life. Inherited is more
useful under SI or under MI when ambiguity doesn't exist.

   >3.  Potential conflict with existing variables, typedefs, of the same name.

   >Big deal...new keywords always cause this problem.  Add a compiler switch
   >on newer compilers to defeat this.

>   It **IS** a big deal. I think that was their conclusion.

True, but basically this is a problem with any new keyword, not a problem
with this specific one.  But if that was their conclusion, so be it...these
are people far more studied in the field than I, and I don't assume
to know more than they.  I'm still learning, and posts like this are so
that I can learn why things are the way they are...

Thanks,

Brian


--
+-----------------------------------------------------------------+
| Brian Hook            | Specializin-----------------+
| Brian Hook            | Specializing in real-time 3D graphics   |
| Box 90315             |-----------------------------------------|
| Gainesville, FL 32607 | Internet: bwh@cis.ufl.edu | Free Tibet! |
+-----------------------------------------------------------------+




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Tue, 31 May 1994 07:19:43 GMT
Raw View
bwh@beach.cis.ufl.edu (Brian Hook) writes:

>I personally would really like such a capability, and I'm sure many others
>that program in a certain "delegate work to derived classes" style would
>find it a benefit.

I agree, it would be a nice capability.

>(Oh, for those that don't know what I'm referring to, it would involve the
>introduction of a new keyword that is automatically set to the parent's
>class type, i.e. class A -> class B, B::foo() { inherited::foo(); } would
>call A::foo() )

This is a very poor description of what should happen.
It is descriptions like this that make people think the typedef
work-around suffices, when in fact it doesn't.
This description leads you to significantly under-sell this proposal.

A better description is that `inherited::member' always refers to
the member that would be selected if the current class had not
defined member.

>1.  Such a keyword isn't necessary because you can do it manually:
>
>class foo : public bar
>{
>   typedef bar inherited;
>};
>
>My answer to this is that it's very error prone, e.g. what happens when you
>introduce a new class in between bar and foo?  Your code will mysteriously
>break.

I would rather say that it is tedious having to change things in two
places rather than error-prone, but yes, this is a good point.

However, you missed the main point, which is that a keyword will
work with multiple inheritance, whereas a typedef won't.

>2.  Such a keyword is ambiguous under MI.

Are you in favor of this idea, or against it? ;-)
You've got it backwards.  The keyword works fine with MI.
It's the typedef work-around that doesn't work with MI.
And that is why a language extension is worthwhile.

--
Fergus Henderson - fjh@munta.cs.mu.oz.au




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Tue, 31 May 1994 07:24:25 GMT
Raw View
mikey@mcs.com (Mike Young) writes:

>bwh@beach.cis.ufl.edu (Brian Hook) writes:
>
>>1.  Such a keyword isn't necessary because you can do it manually:
>
>>class foo : public bar
>>{
>>   typedef bar inherited;
>>};
>
>>My answer to this is that it's very error prone, e.g. what happens when you
>>introduce a new class in between bar and foo?  Your code will mysteriously
>>break.
>
>How would it react with the keyword? It would break, too, in exactly the same
>way unless it did something very counter-intuitive.

No, it would break loudly, rather than breaking quietly.
You would get a warning or an error at compile time, rather than
having your program do the wrong thing at run-time.

>>2.  Such a keyword is ambiguous under MI.
>
>>No different than if the typedef were used, and no different if you called
>>"foo()" that existed in two parent classes.  In other words, this would
>>require (like any other time such ambiguity arose) an explicit
>>qualification.
>
>Disambiguate using a typedef, perhaps?
>Or do you mean something like:
>  inherited::Base1::foo( );
>  inherited::Base2::bar( );

No, you just use Base1::member or Base2::member instead of inherited::member.

--
Fergus Henderson - fjh@munta.cs.mu.oz.au




Author: mikey@mcs.com (Mike Young)
Date: Tue, 31 May 1994 02:31:43
Raw View
In article <9415117.2080@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:

>>>2.  Such a keyword is ambiguous under MI.
>>
>>>No different than if the typedef were used, and no different if you called
>>>"foo()" that existed in two parent classes.  In other words, this would
>>>require (like any other time such ambiguity arose) an explicit
>>>qualification.
>>
>>Disambiguate using a typedef, perhaps?
>>Or do you mean something like:
>>  inherited::Base1::foo( );
>>  inherited::Base2::bar( );

>No, you just use Base1::member or Base2::member instead of inherited::member.

I'm unclear on your statements in an earlier message regarding the proposed
keyword in MI. I recall "Design and Evolution ..." stating that it would not
be work with MI, leaving us Base1:: and Base2:: (class names, not keywords),
as we do now. You appeared to allude to inherited being workable in MI; how
would this be done?

Mike.




Author: bwh@beach.cis.ufl.edu (Brian Hook)
Date: 31 May 1994 11:31:37 GMT
Raw View
In article <9415117.1712@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
>   A better description is that `inherited::member' always refers to
>   the member that would be selected if the current class had not
>   defined member.

I agree, my description was rather poor.  Thank you for the clarification.

>   >2.  Such a keyword is ambiguous under MI.

>   Are you in favor of this idea, or against it? ;-)
>   You've got it backwards.  The keyword works fine with MI.
>   It's the typedef work-around that doesn't work with MI.
>   And that is why a language extension is worthwhile.

My gut feeling is that I'm for the idea, but I haven't heard enough data
from either side of the issue to state unequivocally whether "inherited" is
a good or bad idea.

If "inherited" can be used with MI just fine, I would probably lean towards
liking it a lot.  How would you propose doing this?  I suppose the typical
case would be:

class A { protected: void foo(); };
class B { protected: void foo(); };

class AB : public A, public B
{
   protected:
      void bar() { inherited::foo(); }
};

Thanks,

Brian
--
+-----------------------------------------------------------------+
| Brian Hook            | Specializing in real-time 3D graphics   |
| Box 90315             |-----------------------------------------|
| Gainesville, FL 32607 | Internet: bwh@cis.ufl.edu | Free Tibet! |
+-----------------------------------------------------------------+




Author: bwh@beach.cis.ufl.edu (Brian Hook)
Date: 31 May 1994 11:34:10 GMT
Raw View
In article <mikey.47.00028774@mcs.com> mikey@mcs.com (Mike Young) writes:

>>>>
 I'm unclear on your statements in an earlier message regarding the proposed
 keyword in MI. I recall "Design and Evolution ..." stating that it would not
 be work with MI, leaving us Base1:: and Base2:: (class names, not keywords),
 as we do now. You appeared to allude to inherited being workable in MI; how
 would this be done?
>>>>

I'm not sure, but maybe the poster mean that under MI "inherited" is
basically an invalid concept anyway, since in ambiguous cases the compiler
will be unable to second guess you.  But because "inherited" doesn't
support this particular case, yet makes life a lot simpler/easier for SI,
is that enough reason for it not be seriously considered?

Thanks,

Brian

--
+-----------------------------------------------------------------+
| Brian Hook            | Specializing in real-time 3D graphics   |
| Box 90315             |-----------------------------------------|
| Gainesville, FL 32607 | Internet: bwh@cis.ufl.edu | Free Tibet! |
+-----------------------------------------------------------------+




Author: olaf@cwi.nl (Olaf Weber)
Date: Tue, 31 May 1994 13:54:17 GMT
Raw View
In article <BWH.94May31073137@beach.cis.ufl.edu>, bwh@beach.cis.ufl.edu (Brian Hook) writes:

[...]

> If "inherited" can be used with MI just fine, I would probably lean towards
> liking it a lot.  How would you propose doing this?  I suppose the typical
> case would be:

> class A { protected: void foo(); };
> class B { protected: void foo(); };

> class AB : public A, public B
> {
>    protected:
>       void bar() { inherited::foo(); }
> };

The argument in favour of a keyword is that a more typical case would
be:

struct A { virtual void foo(); };
struct B { virtual void bar(); };

class AB : public A, public B {
protected:
 void foo() { /* ... */ inherited::foo(); }
 void bar() { /* ... */ inherited::bar(); }
};

The typedef trick cannot be made to work in this case, while the
keyword does just fine.

-- Olaf Weber




Author: hugp@actrix.gen.nz (Peter Hug)
Date: Tue, 31 May 1994 21:39:18 GMT
Raw View
In article <BWH.94May30090215@beach.cis.ufl.edu>,
Brian Hook <bwh@beach.cis.ufl.edu> wrote:
>
> I know I know, this has been gone over a million times (in various flame
> wars on comp.lang.c++), but no conclusion has ever really been drawn to my
> satisfaction.  It seems that the odds (this is only hearsay, as I'm not a
> committee member) of introducing an "super" or "inherited" or "derived"
> keyword are pretty slim.
>

IMHO it is one of the issues swept under the carpet by the language
designers. Practitioners are often given examples of how to bypass certain
shortcommings of the language. However, these *fixes* are never quite
satisfactory. The _inherited_ typdef with class scope is just another of
these dirty fixes. Yea, I want a *inherited* keyword too!

When refering to members of instances of classes with multiple bases
(MI) via the inherited keyword, I would expect the inherited keyword
could be used to access members of any of the bases. An additional
notation to resolve conflicts should be provided (of course, resolving
confilicts caused by MI in this way would be no better or worse than the
existing typedef solution).


--
Peter Hug             |                               |  Lieber
Maxi Solutions Ltd    |   Voice: (+64) 4 298 3441     |  arm dran
Paraparaumu Beach     |   Fax:   (+64) 4 297 2288     |  als
New Zealand           |   email: hugp@actrix.gen.nz   |  arm ab




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Tue, 31 May 1994 15:00:52 GMT
Raw View
mikey@mcs.com (Mike Young) writes:

>I'm unclear on your statements in an earlier message regarding the proposed
>keyword in MI. I recall "Design and Evolution ..." stating that it would not
>be work with MI, leaving us Base1:: and Base2:: (class names, not keywords),
>as we do now. You appeared to allude to inherited being workable in MI; how
>would this be done?

I haven't seen D&E yet, so I can't comment on that.  But the basic idea
is that in the rare situations where the use of `inherited::member'
would be ambiguous, the compiler reports an ambiguity error; in the
normal MI case, no ambiguity arises and the compiler can correctly
determine which member is referred to.

 struct A { void a(); };
 struct B { void b(); };

 struct C : A, B {
  void a();
  void b();
  void c() {
   inherited::a();  // A::a();
   inherited::b();  // B::a();
  }
 };

Note that this cannot be faked with a typedef.

--
Fergus Henderson - fjh@munta.cs.mu.oz.au




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Tue, 31 May 1994 15:05:52 GMT
Raw View
bwh@beach.cis.ufl.edu (Brian Hook) writes:

>If "inherited" can be used with MI just fine, I would probably lean towards
>liking it a lot.  How would you propose doing this?  I suppose the typical
>case would be:
>
>class A { protected: void foo(); };
>class B { protected: void foo(); };
>
>class AB : public A, public B
>{
>   protected:
>      void bar() { inherited::foo(); }
>};

In this case, the compiler would report an ambiguity error.  You would
have to explicitly disambiguate by writing A::foo() or B::foo(), just
as you have to do at the moment.  But this case would actually be quite
atypical.  The typical MI case would be

 class A { protected: void foo(); };
 class B { protected: void bar(); };

 class AB : public A, public B
 {
    protected:
       void baz() { inherited::foo(); }
       void quux() { inherited::bar(); }
 };

where no ambiguity occurs.

--
Fergus Henderson - fjh@munta.cs.mu.oz.au




Author: dag@control.lth.se (Dag Bruck)
Date: 01 Jun 1994 06:03:55 GMT
Raw View
>>>>> "B" == Brian Hook <bwh@beach.cis.ufl.edu> writes:

B> Well, I doubt it was "swept under the carpet" by the language
B> designers, but from what I hear it seems very unlikely to be
B> seriously considered.

I bet it will not be considered, because it already was and got voted
down.  As far as I can tell, all arguments that have floated around on
comp.std.c++ were considered at the time.

See also

 Bjarne Stroustrup (1994): The Design and Evolution of C++,
  Addison-Wesley.

pp. 290-292.

     -- Dag




Author: bwh@beach.cis.ufl.edu (Brian Hook)
Date: 01 Jun 1994 11:25:13 GMT
Raw View
In article <DAG.94Jun1080355@bellman.control.lth.se> dag@control.lth.se (Dag Bruck) writes:
>   I bet it will not be considered, because it already was and got voted
>   down.  As far as I can tell, all arguments that have floated around on
>   comp.std.c++ were considered at the time.

I assumed as much, which is why I posted, since I wanted to see what the
general consensus after all was said and done re: "inherited".

>   See also

>    Bjarne Stroustrup (1994): The Design and Evolution of C++,
>     Addison-Wesley.

I already did, and quoted it, and it wasn't detailed enough, thus my posts.

Brian
--
+-----------------------------------------------------------------+
| Brian Hook            | Specializing in real-time 3D graphics   |
| Box 90315             |-----------------------------------------|
| Gainesville, FL 32607 | Internet: bwh@cis.ufl.edu | Free Tibet! |
+-----------------------------------------------------------------+




Author: craffert@csfb1.fir.fbc.com (Colin Owen Rafferty)
Date: Tue, 31 May 1994 18:02:51 GMT
Raw View
In article <BWH.94May31073137@beach.cis.ufl.edu> bwh@beach.cis.ufl.edu (Brian Hook) writes:
> In article <9415117.1712@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:

>>> 2.  Such a keyword is ambiguous under MI.

>> You've got it backwards.  The keyword works fine with MI.
>> It's the typedef work-around that doesn't work with MI.
>> And that is why a language extension is worthwhile.

> If "inherited" can be used with MI just fine, I would probably lean towards
> liking it a lot.  How would you propose doing this?  I suppose the typical
> case would be:

> class A { protected: void foo(); };
> class B { protected: void foo(); };

> class AB : public A, public B
> {
>    protected:
>    void bar() { inherited::foo(); }
> };

In your case, neither the keyword nor the typedef would work.  Fergus is
correct.  The typical case would more likely be:

class A { protected: void foo(); };
class B { protected: void bar(); };

class AB : public A, public B
{
   protected:
   void foo() { inherited::foo(); inherited::bar(); }
};

The typedef would not work in this case, but the keyword would.  In
general, if you use MI correctly, you shouldn't have name conflicts,
because your base classes ought to be orthogonal.
--
Colin Rafferty          Work: (212) 909 4529    Beeper: (800) 225 0256 x311944
CS First Boston         Home: (212) 663 3401            (917) 321 1733
--
The biggest problem with C++ is not that it's complex or C compatible.
It's that not enough people know enough about it to train others.
-John (Max) Skaller




Author: bwh@beach.cis.ufl.edu (Brian Hook)
Date: 01 Jun 1994 03:08:58 GMT
Raw View
In article <Cqos5J.95y@actrix.gen.nz> hugp@actrix.gen.nz (Peter Hug) writes:
>   IMHO it is one of the issues swept under the carpet by the language
>   designers. Practitioners are often given examples of how to bypass certain
>   shortcommings of the language. However, these *fixes* are never quite
>   satisfactory. The _inherited_ typdef with class scope is just another of
>   these dirty fixes. Yea, I want a *inherited* keyword too!

Well, I doubt it was "swept under the carpet" by the language designers,
but from what I hear it seems very unlikely to be seriously considered.
The (widely known) problem is that everyone has some specific feature or
keyword or what not that would make their life oh so much better -- and you
get a language that is way too bloated if all of these are approved.

Note that I didn't say I _wanted_ the keyword -- I was trying to find a
more thorough description of why it was not seriously considered.  The
section in D&E that addresses this issue discusses that a workaround is
available.  Well, it's true that a workaround is available for just about
anything.

So then the question/point is:  How often is "inherited" used?  How much
would its convenience outweigh its penalties?  It would obviously have NO
run-time penalties, which is a big concern, and having a compiler support
it should be fairly trivial -- no, make that ABSOLUTELY trivial.

So then the only other issues (that I can think of off the top of my head)
are:  incompatibility with existing variable names, adding a new keyword,
and proving that it's useful and provides enough of a convenience that it
is worthwhile to implement and support.

For the first one, this can usually be taken care of with one recompile --
the compiler would simply error out all places that it was used as a
variable or function name -- hell, a "sed" script could handle this!

For the second issue, I don't know how religious the ANSI/ISO committee is
about keywords -- they didn't seem to have a problem with "and", "or", and
all those others, nor with "mutable" and the host of others added.

Third,

>   When refering to members of instances of classes with multiple bases
>   (MI) via the inherited keyword, I would expect the inherited keyword
>   could be used to access members of any of the bases. An additional
>   notation to resolve conflicts should be provided (of course, resolving
>   confilicts caused by MI in this way would be no better or worse than the
>   existing typedef solution).

As has been pointed out, conflicts because of MI only arise when two parent
classes have the same member function.  Under certain situations, however,
"inherited" will still work whereas the typedef does not.  Under other
situations, neither the typedef nor the keyword will help, but some
assert that this is a design problem.  I don't have enough experience in
the field to make that kind of a sweeping statement.

Some state that because it doesn't solve the MI ambiguity problem that
"inherited" adds little value to the language.  I disagree, since I'm not
positive that the MI ambiguity problem arises enough to be a valid
consideration.  I would rather have a solution that works 90% of the time
than one that doesn't work 50% of the time and is a pain in the ass to
maintain.

It would be interesting to look at existing class libraries and
applications from many different sources to see how often an "inherited"
type situation is used.  And in these sources I would like to see how
common MI ambiguity arises....

Brian


--
+-----------------------------------------------------------------+
| Brian Hook            | Specializing in real-time 3D graphics   |
| Box 90315             |-----------------------------------------|
| Gainesville, FL 32607 | Internet: bwh@cis.ufl.edu | Free Tibet! |
+-----------------------------------------------------------------+




Author: bs@alice.att.com (Bjarne Stroustrup)
Date: 2 Jun 94 12:03:17 GMT
Raw View

You can find a summary of the reasoning for and against inherited:: in

 Bjarne Stroustrup
 The Design and Evolution of C++
 Addison Wesley, ISBN 0-201-54330-3.
 March 1994.

look for `inherited' in the index.




Author: barmar@think.com (Barry Margolin)
Date: 2 Jun 1994 17:25:48 GMT
Raw View
In article <mikey.47.00028774@mcs.com> mikey@mcs.com (Mike Young) writes:
[In reply to article <9415117.2080@mulga.cs.mu.OZ.AU> by fjh@munta.cs.mu.OZ.AU (Fergus Henderson):
>You appeared to allude to inherited being workable in MI; how
>would this be done?

The "inherited" keyword works with MI in the case where a member is only
inherited from one of its bases.  inherited::member() will then select that
unique member.  If a member is inherited from multiple bases, you still
need to use Base1::member() or Base2::member() to disambiguate.

That was the point in one of his first messages, where he said that
inherited::member refers to the member that would have been selected if the
current class didn't define such a member.
--
Barry Margolin
System Manager, Thinking Machines Corp.

barmar@think.com          {uunet,harvard}!think!barmar




Author: jamshid@ses.com (Jamshid Afshar)
Date: Thu, 2 Jun 1994 22:57:54 GMT
Raw View
In article <BWH.94Jun1072513@beach.cis.ufl.edu>,
Brian Hook <bwh@beach.cis.ufl.edu> wrote:
>>   See also
>>    Bjarne Stroustrup (1994): The Design and Evolution of C++,
>>     Addison-Wesley.
>
>I already did, and quoted it, and it wasn't detailed enough, thus my posts.

I'm not sure what exactly you were looking for, but to me D&E seemed
very clear and enlightening on this subject.  Here's much of D&E 13.6
Inherited:

 I had considered [an inherited keyword] early on in the design
 of C++, but had rejected it in favor of qualification with the
 base class name because that solution could handle multiple
 inheritance, and inherted:: clearly can't.  However, Dag
 observed that the two schemes would deal with all problems
 without introducing loopholes: [...example showing why and how
 an inherited keyword is still useful in MI (even more useful
 than a typedef...].

 I was convinced by these arguments and by the meticulous
 paperwork that documented its details.  Here was a proposal
 that was clearly useful, easily understood, and trivial to
 implement. [...]

 After the final discussion of this proposal in the committee
 Dag volunteered it as a textbook example of a good idea that
 shouldn't be accepted:

    "[...] we soon agreed that the proposal was free of major
    flaws. [...] it correctly dealt with the ambiguities that
    can arise with multiple inheritance is used.  We also
    agreed that the proposal was trivial to implement and would
    in fact be helpful to programmers.  Note that this is *not*
    sufficient for acceptance.  If we accepted [all such
    proposals] the language would sink under its own weight.
    We will never know if this proposal would have passed,
    though, because at this point in the discussion, Michael
    Tiemann [showed the "inherited" typedef workaround].

 Given this technique, we decided that our efforts were better
 spent on some other standards work.  The benefits of
 inherited:: as a built-in facility didn't sufficiently
 outweigh the benefits of what the programmer could do with
 existing features.  In consequence, we decided not to make
 inherited:: one of the very few extensions we could afford to
 accept for C++.

So, I think it's clear that a `inherited' keyword would have worked
well, contrary to what some people are saying in this thread (and what
I thought until a c.l.c++ thread a couple of months ago).  Whether
ANSI/ISO should have gone ahead and accepted it is debatable.  I think
my personal opinion now is that they should have, but it's not a huge
deal to me.

Jamshid Afshar
jamshid@ses.com