Topic: ++ on enumerations


Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/29
Raw View
Ben Elliston <bje@compucat.com.au> writes:

|>  > Section 5.3.2 states that "the type of the operand [for ++ and --]
|>  > share be an arithmetic type or a pointer to a completely-defined
|>  > object type." Why aren't enumerated types allowed?
|>
|>  Good question.  But what would the behaviour be if you decremented below
|>  0 or incremented above the maximum enumeration?  Throw an exception,
|>  perhaps?

What is the behavior if an int is decremented beyond INT_MIN?  This
problem isn't specific to enum's.

On the other hand, there is the question of what to do when the enum
values aren't contiguous.

|>  Of course, what you are describing could be implemented within a class,
|>  provided with overloaded ++ and -- operators.  Perhaps that's why it was
|>  left out of the language?

The standards committee explicitly added the possibility of overloading
on an enum type, precisely to support this (without the necessity of
encapsulating in a class).

--
James Kanze      home:     kanze@gabi-soft.fr        +33 (0)1 39 55 85 62
                 office:   kanze@vx.cit.alcatel.fr   +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
     -- Conseils en informatique industrielle --
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/29
Raw View
David R Tribble <david.tribble@central.beasys.com> writes:

|>  Ray Lischner <lisch@tempest-sw.com> wrote:
|>  > Section 5.3.2 states that "the type of the operand [for ++ and --]
|>  > share be an arithmetic type or a pointer to a completely-defined
|>  > object type." Why aren't enumerated types allowed?
|>
|>  They are - enumerated types are arithmetic types.  (Arithmetic types
|>  include all of the character, integer, enumerated, and float types.)

They aren't.  In an arithmetic context, an enum type is "promoted" to
its underlying integer type (at least int).  This is a type conversion,
the results of which are not an lvalue.  And of course, operator++
requires an lvalue.

--
James Kanze      home:     kanze@gabi-soft.fr        +33 (0)1 39 55 85 62
                 office:   kanze@vx.cit.alcatel.fr   +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
     -- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Pete Becker <pbecker@oec.com>
Date: 1997/01/30
Raw View
David R Tribble wrote:
>
> Ray Lischner <lisch@tempest-sw.com> wrote:
> > Section 5.3.2 states that "the type of the operand [for ++ and --]
> > share be an arithmetic type or a pointer to a completely-defined
> > object type." Why aren't enumerated types allowed?
>
> They are - enumerated types are arithmetic types.  (Arithmetic types
> include all of the character, integer, enumerated, and float types.)

NO!!! In C enumerated types are arithmetic types, but in C++ they are
not. You cannot apply ++ or -- to an enumerated type in C++ unless you
have an explicit definition for that operator on that type.
 -- Pete
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: David R Tribble <david.tribble@central.beasys.com>
Date: 1997/01/30
Raw View
I, David R Tribble <david.tribble@central.beasys.com> wrote:

|>  Ray Lischner <lisch@tempest-sw.com> wrote:
|>  > Section 5.3.2 states that "the type of the operand [for ++ and --]
|>  > share be an arithmetic type or a pointer to a completely-defined
|>  > object type." Why aren't enumerated types allowed?
|>
|>  They are - enumerated types are arithmetic types.  (Arithmetic types
|>  include all of the character, integer, enumerated, and float types.)

James Kanze responded:
> They aren't.  In an arithmetic context, an enum type is "promoted" to
> its underlying integer type (at least int).  This is a type conversion,
> the results of which are not an lvalue.  And of course, operator++
> requires an lvalue.

My mistake.  I assumed that enum types (which Stroustrup admits were
borrowed somewhat reluctantly from C) were based on the semantics of C.
They aren't, because enum types in C are considered arithmetic types,
while C++ considers them as special user-defined types (not quite on par
with classes, though).

It would be nice if they were more class-like, though, so you could do
this:

    class Base
    {
    protected:
        enum Color  { RED, GREEN, BLUE };
        ...
    };

    class Derived: public Base
    {
    protected:
        enum MoreColor: Color { CYAN, YELLOW, MAGENTA };
        ...
    };

This would allow MoreColor to add on top of the values already assigned
to Color by 'inheriting' from it.  (Something like this can be done in
Eiffel.)  Using colors for enum values is a bit contrived; a more realistic
example would be error codes, where Base defined some basic error codes and
Derived added to the list.  If Derived's enum could inherit from Base's enum,
then Derived's enum values could be guaranteed unique, even if Base's enum
values were changed.

-- David R. Tribble, david.tribble@central.beasys.com --
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: James Kuyper <kuyper@wizard.net>
Date: 1997/01/29
Raw View
David Sachs wrote:
>
> James Kuyper <kuyper@wizard.net> writes:
>
> >...
> >The basic idea is that each enumeration value represents a distinct
> >case, with no numerical connection to any other case, so ++ and --
> >should be
> >meaningless. If ++ and -- are meaningful, you should have used an 'int'
> >instead. Of course, this abstract point of view ignores practical
> >problems, like how do you loop over all valid values of an enumeration
> >type? There is no general solution to this problem, just solutions that
> >depend upon the precise values chosen.
> >---
> Actually, you can overload the ++ operator for enums, and sometimes
> this is meaningful. Example:
>
> enum season { winter, spring, summer, fall };
>
> season& operator ++ (season & s)
> {
>   switch (s)
>   {
>     case winter: s = spring; break;
>
>     case spring: s = summer; break;
>
>     case summer: s = fall; break;
>
>     case fall: s = winter; break;
>   }
>   return s;
> }
As I said: this is a case of a solution that depends upon the fact that
you have chosen four values, and that they have particular names. A
similar solution can be applied to any specific case, but there is no
general solution. Also, arguably you should have defined this as an
integer with modulo 4 arithmetic; The sum and difference of any two
values, modulus 4, has a very real significance. You could easily create
a template for modulus N numbers, with overloaded arithmetic operators.
This would be more appropriate than a pure enumeration.


[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/31
Raw View
David R Tribble <david.tribble@central.beasys.com> writes:

    [Concerning enum's...]
|>  It would be nice if they were more class-like, though, so you could do
|>  this:
|>
|>      class Base
|>      {
|>      protected:
|>          enum Color  { RED, GREEN, BLUE };
|>          ...
|>      };
|>
|>      class Derived: public Base
|>      {
|>      protected:
|>          enum MoreColor: Color { CYAN, YELLOW, MAGENTA };
|>          ...
|>      };
|>
|>  This would allow MoreColor to add on top of the values already assigned
|>  to Color by 'inheriting' from it.  (Something like this can be done in
|>  Eiffel.)  Using colors for enum values is a bit contrived; a more realistic
|>  example would be error codes, where Base defined some basic error codes and
|>  Derived added to the list.  If Derived's enum could inherit from Base's
|>  enum, then Derived's enum values could be guaranteed unique, even if Base's
|>  enum values were changed.

Except that you don't want to do this, generally, since it means that a
Derived can no longer be substituted for a Base (since it may return
error codes the user is not prepared to handle, being unknown to him).

--
James Kanze      home:     kanze@gabi-soft.fr        +33 (0)1 39 55 85 62
                 office:   kanze@vx.cit.alcatel.fr   +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
     -- Conseils en informatique industrielle --
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: David R Tribble <david.tribble@central.beasys.com>
Date: 1997/01/31
Raw View
I wrote [concerning enums in derived classes that can inherit from enums in
the base class]:
|>  ...  Using colors for enum values is a bit contrived; a more realistic
|>  example would be error codes, where Base defined some basic error codes and
|>  Derived added to the list.  If Derived's enum could inherit from Base's
|>  enum, then Derived's enum values could be guaranteed unique, even if Base's
|>  enum values were changed.

James Kanze responded:
> Except that you don't want to do this, generally, since it means that a
> Derived can no longer be substituted for a Base (since it may return
> error codes the user is not prepared to handle, being unknown to him).

That implies that a base class must define all the error codes that it and
any of its descendants will ever use.  Or that all derived classes must
invent their own, completely separate, error codes, which may entail
duplicating the base class's codes.

Truly polymorphic code will not have to worry about this, since a derived
class knows how to deal with its own error codes; the base type is more
likely to be used in a polymorphic pointer, so that it can point to any
of the derived subtypes, each one handling and ascribing meaning to its own
error codes (which extend the base class's codes).
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Gerard Weatherby <gerard.weatherby@snet.net>
Date: 1997/01/31
Raw View
David R Tribble wrote:

> It would be nice if they were more class-like, though, so you could do
> this:
>
>     class Base
>     {
>     protected:
>         enum Color  { RED, GREEN, BLUE };
>         ...
>     };
>
>     class Derived: public Base
>     {
>     protected:
>         enum MoreColor: Color { CYAN, YELLOW, MAGENTA };
>         ...
>     };
>
> This would allow MoreColor to add on top of the values already assigned
> to Color by 'inheriting' from it.
Well, you can always do:
  class Base
    {
    protected:
        enum Color  { RED, GREEN, BLUE, MAX = BLUE };
    };

    class Derived: public Base
    {
 public:
  void listColor( );
    protected:
        enum MoreColor{ BLUE = Base::BLUE,
   GREEN = Base::GREEN,
   RED = Base::RED,       CYAN = MAX + 1, YELLOW, MAGENTA };
    };


which has a similar effect.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Stephen.Clamage@eng.sun.com (Steve Clamage)
Date: 1997/02/01
Raw View
In article 002c0a78@central.beasys.com, David R Tribble
<david.tribble@central.beasys.com> writes:
>I wrote [concerning enums in derived classes that can inherit from enums in
>the base class]:
>|>  ...  Using colors for enum values is a bit contrived; a more realistic
>|>  example would be error codes, where Base defined some basic error codes
>|>  and Derived added to the list.  If Derived's enum could inherit from
>|>  Base's enum, then Derived's enum values could be guaranteed unique, even
>|>  if Base's enum values were changed.
>
>James Kanze responded:
>> Except that you don't want to do this, generally, since it means that a
>> Derived can no longer be substituted for a Base (since it may return
>> error codes the user is not prepared to handle, being unknown to him).
>
>That implies that a base class must define all the error codes that it and
>any of its descendants will ever use.

Not at all. C++ requires two things of enums that C does not:
1. The implementation of an enum type must use enough bits to store
all values in the full range of the defined enumerators (the
representation must be binary, as with integers).
2. All values representable in that number of bits are allowed for the
enum type.

Thus, we can later define constants of the enum type that do not match
any of the enumerators, and use them as if they were predefined
enumerators. Example:

 enum diagnostic { warning=0, serious=3000, fatal=6000 };

We can later, in any suitable scope (e.g. a derived class), add new
named constants in the range 0-8191:

 const diagnostic not_elegant = diagnostic(warning+1);
 const diagnostic rule_violation = diagnostic(serious+1);
 const diagnostic capacity_exceeded = diagnostic(fatal+1);

You can use these new constants in exactly the ways you would use
"serious", for example.
---
Steve Clamage, stephen.clamage@eng.sun.com
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Abhishek Chauhan <Abhishek.Chauhan@Eng.Sun.COM>
Date: 1997/02/03
Raw View
David R Tribble <david.tribble@central.beasys.com> writes:
<talking of enums in c++>
> It would be nice if they were more class-like, though, so you could
> do
>     class Base
>     {
>     protected:
>         enum Color  { RED, GREEN, BLUE };
>         ...
>     };
>
>     class Derived: public Base
>     {
>     protected:
>         enum MoreColor: Color { CYAN, YELLOW, MAGENTA };
>         ...
>     };
>
> This would allow MoreColor to add on top of the values already assigned
> to Color by 'inheriting' from it.  (Something like this can be done in
> Eiffel.)

Here is a way to effectively add more enumerators into an enum:

// the enum
enum Color { RED, GREEN, BLUE, ColorMax = INT_MAX };

// the extensions
const Color CYAN = Color(10);
const Color YELLOW = Color(11);
const Color MAGENTA = Color(12);

these new values can now be effectively used just like the ones
defined in the enum. I think I read about this technique in one of
Steve Clamage's posts some time earlier..

Whether you want to do this is another question. I normally use an
enum to indicate a fixed set of possiblities. And use a switch to
select cases based on the enum. I consider the case of each possible
value defined in the enum, and rest in peace that I have considered
all possible cases. In fact my compiler warns if I switch on an enum
and don't consider all possible values defined for the enum. Adding
new "members" to the enum like this seems dangerous, since I may not
see at one place what all possible the values that the enum can take
are.

abhishek
---
Abhishek Chauhan, abhishek.chauhan@sun.com
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: lisch@tempest-sw.com (Ray Lischner)
Date: 1997/01/26
Raw View
Section 5.3.2 states that "the type of the operand [for ++ and --]
share be an arithmetic type or a pointer to a completely-defined
object type." Why aren't enumerated types allowed?
--
Ray Lischner                                    lisch@tempest-sw.com
Tempest Software, Inc., Corvallis, Oregon, USA  http://www.tempest-sw.com
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/01/27
Raw View
lisch@tempest-sw.com (Ray Lischner) writes:

>Section 5.3.2 states that "the type of the operand [for ++ and --]
>share be an arithmetic type or a pointer to a completely-defined
>object type." Why aren't enumerated types allowed?

What should `++' do for the enums like the following?

 enum Horrible { foo = -42, bar = 1027, baz = -43 };

If `++' is appropriate for a particular enum, then you can
always define it yourself.

 Horrible& operator ++ (Horrible& x) {
  switch(x) {
  case foo: x = bar; break;
  case bar: x = baz; break;
  case baz: x = foo; break;
  default:  assert(0);
  }
  return x;
 }

--
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: b91926@fsui02.fnal.gov (David Sachs)
Date: 1997/01/27
Raw View
James Kuyper <kuyper@wizard.net> writes:

>...
>The basic idea is that each enumeration value represents a distinct
>case, with no numerical connection to any other case, so ++ and --
>should be
>meaningless. If ++ and -- are meaningful, you should have used an 'int'
>instead. Of course, this abstract point of view ignores practical
>problems, like how do you loop over all valid values of an enumeration
>type? There is no general solution to this problem, just solutions that
>depend upon the precise values chosen.
>---
Actually, you can overload the ++ operator for enums, and sometimes
this is meaningful. Example:

enum season { winter, spring, summer, fall };

season& operator ++ (season & s)
{
  switch (s)
  {
    case winter: s = spring; break;

    case spring: s = summer; break;

    case summer: s = fall; break;

    case fall: s = winter; break;
  }
  return s;
}
--
** The Klingons' favorite food was named by the first earthling to see it **
David Sachs - Fermilab, MSSG MS369 - P. O. Box 500 - Batavia, IL 60510
Voice: 1 630 840 3942      Department Fax: 1 630 840 3785


[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Pete Becker <pbecker@oec.com>
Date: 1997/01/27
Raw View
Ray Lischner wrote:
>
> Section 5.3.2 states that "the type of the operand [for ++ and --]
> share be an arithmetic type or a pointer to a completely-defined
> object type." Why aren't enumerated types allowed?

enum tricky { first = 0, second = 3, third = 5, fourth = 99 };

While it's not particularly difficult to generate code to handle
incrementing an enum of this type, there doesn't seem to be a pressing
need for it. In cases where it is needed you can explicitly provide
increment and decrement operators for your enum, and implement the logic
yourself.
 -- Pete
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: James Kuyper <kuyper@wizard.net>
Date: 1997/01/27
Raw View
Ray Lischner wrote:
>
> Section 5.3.2 states that "the type of the operand [for ++ and --]
> share be an arithmetic type or a pointer to a completely-defined
> object type." Why aren't enumerated types allowed?
...
The basic idea is that each enumeration value represents a distinct
case, with no numerical connection to any other case, so ++ and --
should be
meaningless. If ++ and -- are meaningful, you should have used an 'int'
instead. Of course, this abstract point of view ignores practical
problems, like how do you loop over all valid values of an enumeration
type? There is no general solution to this problem, just solutions that
depend upon the precise values chosen.
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Ben Elliston <bje@compucat.com.au>
Date: 1997/01/28
Raw View
> Section 5.3.2 states that "the type of the operand [for ++ and --]
> share be an arithmetic type or a pointer to a completely-defined
> object type." Why aren't enumerated types allowed?

Good question.  But what would the behaviour be if you decremented below
0 or incremented above the maximum enumeration?  Throw an exception,
perhaps?

Of course, what you are describing could be implemented within a class,
provided with overloaded ++ and -- operators.  Perhaps that's why it was
left out of the language?

Cheers,
Ben

--
Ben Elliston    E-mail: ben.elliston@compucat.com.au
Compucat Research Pty Limited  WWW: <http://www.compucat.com.au>
Fyshwick ACT Australia
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: David R Tribble <david.tribble@central.beasys.com>
Date: 1997/01/28
Raw View
Ray Lischner <lisch@tempest-sw.com> wrote:
> Section 5.3.2 states that "the type of the operand [for ++ and --]
> share be an arithmetic type or a pointer to a completely-defined
> object type." Why aren't enumerated types allowed?

They are - enumerated types are arithmetic types.  (Arithmetic types
include all of the character, integer, enumerated, and float types.)

Enumerated constants are little more that 'named integer constant values'
(quoting from ANSI C 6.1.2.5; see also 6.2.1 and 6.5.2.2).  Thus enum
types are little more than 'named integer types'.

True, each enum type is a unique user-defined type (though not quite on
par with class types).  That's why the example in Stroustrup's D&E (p.254)
works:

> enum Season { winter, spring, summer, fall };
>
> Season operator ++(Season s)
> {
>     switch (s)
>     {
>     case winter: return spring;
>     case spring: return summer;
>     case summer: return fall;
>     case fall:   return winter;
>     default:     return winter;     // Handle invalid values
>     }
> }

Enum type 'Season' is considered a new type, so overloading functions
on it, including operator++(), works.  But operator++() works on it
by default anyway, since 'Season' is an arithmetic type.  The overloaded
version is safer, though, since it results in well-defined results no
matter what values are given for the ++ operand.

-- David R. Tribble, david.tribble@central.beasys.com --
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]