Topic: typedef as class synonym


Author: "Jonathan H Lundquist" <fluxsmith@fluxsmith.com>
Date: 1998/11/05
Raw View
I've been declaring classes as follows:

class A {
};

class B : public A {
   typedef A base;

   B() : base() {}
   // various other constructors
};

The idea was that if for any reason the name of 'A' was changed, you would
only have to change the base class name and the typedef, you would not have
to change all of the constructors and various other members with calls to
the base class.

MSVC warns about typedef being used as synonym for class, and today I
discovered in 'compliant' mode the warning is an error.

My questions are:
1. Does the standard really prohibit this?
2. If so, why?
3. Would the above usage be justification for allowing it?

Thank you.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: sbnaran@localhost.localdomain.COM (Siemel Naran)
Date: 1998/11/05
Raw View
On 05 Nov 98 09:16:03 GMT, Jonathan H Lundquist <fluxsmith@fluxsmith.com> wrote:

>class A {
>};
>
>class B : public A {
>   typedef A base;
>
>   B() : base() {}
>   // various other constructors
>};


>1. Does the standard really prohibit this?

No.  It is valid and useful for notation.


>2. If so, why?
>3. Would the above usage be justification for allowing it?


However, you can't do this:

class A
{
     typedef A self;
     self();
};

--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 1998/11/05
Raw View
"Jonathan H Lundquist" <fluxsmith@fluxsmith.com> writes:

 >I've been declaring classes as follows:
 >
 >class A {
 >};
 >
 >class B : public A {
 >   typedef A base;
 >
 >   B() : base() {}
 >   // various other constructors
 >};
...
 >MSVC warns about typedef being used as synonym for class, and today I
 >discovered in 'compliant' mode the warning is an error.
 >
 >My questions are:
 >1. Does the standard really prohibit this?

No, it does not.

The relevant text from the standard is 10/1 and 7.1.3/4.
10/1 says that the name in a base-specifier must be a class-name:

 | The class-name in a base-specifier shall not be an incompletely
 | defined class (clause class); this class is called a direct base class
 | for the class being declared. During the lookup for a base class name,
 | non-type names are ignored (basic.scope.hiding). If the name found is
 | not a class-name, the program is ill-formed.

But 7.1.3/4 comes to the rescue, by allowing typedefs as class-names:

 | A typedef-name that names a class is a class-name (class.name).

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3        |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Jerry Leichter <leichter@smarts.com>
Date: 1998/11/05
Raw View
| I've been declaring classes as follows:
|
| class A {
| };
|
| class B : public A {
|    typedef A base;
|
|    B() : base() {}
|    // various other constructors
| };
|
| ...MSVC warns about typedef being used as synonym for class, and today
| I discovered in 'compliant' mode the warning is an error.
|
| My questions are:
| 1. Does the standard really prohibit this? ...

[This may have changed between the FDS and the actual standard, but I
doubt it.]  There's an example exactly on point (Section 12.6.2,
Initializing bases and members, paragraph 2):

2 Names in a mem-initializer-id are looked up in the scope of  the  con-
  structor's class and, if not found in that scope, are looked up in the
  scope containing the constructor's definition.   Unless  the  mem-ini-
  tializer-id  names  a nonstatic data member of the constructor's class
  or a direct or virtual base of that class, the mem-initializer is ill-
  formed.   A mem-initializer-list can initialize a base class using any
  name that denotes that base class type.  [Example:
          struct A { A(); };
          typedef A global_A;
          struct B { };
          struct C: public A, public B { C(); };
          C::C(): global_A() { }    // mem-initializer for base A
   --end example]

So MSVC is wrong again....
       -- Jerry
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Biju Thomas <bijuthom@ibm.net>
Date: 1998/11/05
Raw View
Jonathan H Lundquist wrote:
>
> I've been declaring classes as follows:
>
> class A {
> };
>
> class B : public A {
>    typedef A base;
>
>    B() : base() {}
>    // various other constructors
> };
>
> The idea was that if for any reason the name of 'A' was changed, you would
> only have to change the base class name and the typedef, you would not have
> to change all of the constructors and various other members with calls to
> the base class.
>
> MSVC warns about typedef being used as synonym for class, and today I
> discovered in 'compliant' mode the warning is an error.
>
> My questions are:
> 1. Does the standard really prohibit this?
> 2. If so, why?
> 3. Would the above usage be justification for allowing it?
>

It is legal, but be beware of surprises, if you forget to put the
typedef in some class, and you declare the typedef as public. See the
following code:

#include <iostream>

class A
{
public:
  virtual void foo () {  std::cout << "A" << std::endl; }
};

class B : public A
{
  typedef A Base;
public:
  virtual void foo () { Base::foo(); std::cout << "B" << std::endl; }
};

class C : public B
{
public:
  virtual void foo () { Base::foo(); std::cout << "C" << std::endl; }
};

int main ()
{
  C aC;
  aC.foo();

  return 0;
}

It prints:
  A
  C

where I would have meant:
  A
  B
  C

The fact that class C can access a private type inside class B looks
like a bug to me (MSVC 5.0).

Regards,
Biju Thomas
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]