Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Enumerations

Reply
Thread Tools

Enumerations

 
 
Christopher Benson-Manica
Guest
Posts: n/a
 
      07-21-2004
I'll try to explain what I want to do:

I have foo.h and foo.cpp. Units that include foo.h will define an
enumeration bar:

enum bar { typeNone, typeBaz, typeQuux, ... , count };

A method defined in foo.cpp needs to return typeNone. Is using

static_cast< bar >( 0 )

acceptable?

Also, methods in foo.cpp need to return typeBaz, typeQuux, etc. Is
there any way to specify that these are values of the bar enumeration
without actually defining bar (since units that include foo.h will
take care of that)?

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
 
Reply With Quote
 
 
 
 
Steve
Guest
Posts: n/a
 
      07-21-2004
On 21/7/04 8:46 pm, in article cdmh6d$5mk$(E-Mail Removed), "Christopher
Benson-Manica" <(E-Mail Removed)> wrote:

> I'll try to explain what I want to do:
>
> I have foo.h and foo.cpp. Units that include foo.h will define an
> enumeration bar:
>
> enum bar { typeNone, typeBaz, typeQuux, ... , count };
>
> A method defined in foo.cpp needs to return typeNone. Is using
>
> static_cast< bar >( 0 )
>
> acceptable?



Am I missing something obvious? Why not just return typeNone?


> Also, methods in foo.cpp need to return typeBaz, typeQuux, etc. Is
> there any way to specify that these are values of the bar enumeration
> without actually defining bar (since units that include foo.h will
> take care of that)?



Is foo.cpp #including foo.h?


Steve.

 
Reply With Quote
 
 
 
 
Steve
Guest
Posts: n/a
 
      07-21-2004
On 21/7/04 8:50 pm, in article BD248795.89586%root@127.0.0.1, "Steve"
<root@127.0.0.1> wrote:

> On 21/7/04 8:46 pm, in article cdmh6d$5mk$(E-Mail Removed), "Christopher
> Benson-Manica" <(E-Mail Removed)> wrote:
>
>> I'll try to explain what I want to do:
>>
>> I have foo.h and foo.cpp. Units that include foo.h will define an
>> enumeration bar:
>>
>> enum bar { typeNone, typeBaz, typeQuux, ... , count };
>>
>> A method defined in foo.cpp needs to return typeNone. Is using
>>
>> static_cast< bar >( 0 )
>>
>> acceptable?

>
>
> Am I missing something obvious? Why not just return typeNone?
>
>
>> Also, methods in foo.cpp need to return typeBaz, typeQuux, etc. Is
>> there any way to specify that these are values of the bar enumeration
>> without actually defining bar (since units that include foo.h will
>> take care of that)?

>
>
> Is foo.cpp #including foo.h?
>
>
> Steve.
>



Oops, sorry, let me read the OP again more closely...

OK, let me rephrase my answer...

Why not put the enum declaration in foo.h?


Steve.

 
Reply With Quote
 
Christopher Benson-Manica
Guest
Posts: n/a
 
      07-21-2004
Steve <root@127.0.0.1> spoke thus:

> Am I missing something obvious? Why not just return typeNone?


My intent is that neither foo.h nor foo.cpp will actually define bar,
perhaps something like

foo.h:

enum bar;

foo.cpp

#include "foo.h"

/* whatever

my_special_unit.cpp:

#include "foo.h"

enum bar { typeNone, typeBaz, count };

some_other_unit.cpp:

#include "foo.h"

enum bar { typeNone, typeQuux, typeCharlie, count };

Presumably this won't work, since the bar enumeration is never fleshed
out for foo.cpp. Basically, I want to make the symbols that the
enumeration will use available to foo.cpp without actually defining
the enumeration there. Does that make sense? Is it possible?

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
 
Reply With Quote
 
Peter van Merkerk
Guest
Posts: n/a
 
      07-21-2004
Christopher Benson-Manica wrote:
> Steve <root@127.0.0.1> spoke thus:
>
>
>>Am I missing something obvious? Why not just return typeNone?

>
>
> My intent is that neither foo.h nor foo.cpp will actually define bar,
> perhaps something like
>
> foo.h:
>
> enum bar;
>
> foo.cpp
>
> #include "foo.h"
>
> /* whatever
>
> my_special_unit.cpp:
>
> #include "foo.h"
>
> enum bar { typeNone, typeBaz, count };
>
> some_other_unit.cpp:
>
> #include "foo.h"
>
> enum bar { typeNone, typeQuux, typeCharlie, count };
>
> Presumably this won't work, since the bar enumeration is never fleshed
> out for foo.cpp. Basically, I want to make the symbols that the
> enumeration will use available to foo.cpp without actually defining
> the enumeration there. Does that make sense? Is it possible?


If you need to use the enum as a return type and the function must be
declared in the .h file (which is the case if I understood the original
question correctly) the answer is no. Only if the enum is used only
inside function in the .cpp file but never as return type or argument
the enum can be declared inside the .cpp file.

In case of a class you might consider putting the enum definition in the
private section of the class. That way it is clear that the enum is
intended for internal use only, and isn't accessible to the outside
world. Another advantage is that it is defined within the scope of the
class, so potential name clashes are avoided.


--
Peter van Merkerk
peter.van.merkerk(at)dse.nl
 
Reply With Quote
 
Christopher Benson-Manica
Guest
Posts: n/a
 
      07-21-2004
Peter van Merkerk <(E-Mail Removed)> spoke thus:

> In case of a class you might consider putting the enum definition in the
> private section of the class. That way it is clear that the enum is
> intended for internal use only, and isn't accessible to the outside
> world. Another advantage is that it is defined within the scope of the
> class, so potential name clashes are avoided.


Well, here's another question: If I put the enum definition in the
class, can a subclass override that definition?

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
 
Reply With Quote
 
JKop
Guest
Posts: n/a
 
      07-21-2004
Without passing judgement on your design:

extern enum bar;

return bar(0);


-JKop
 
Reply With Quote
 
Christopher Benson-Manica
Guest
Posts: n/a
 
      07-21-2004
JKop <(E-Mail Removed)> spoke thus:

> Without passing judgement on your design:


No, please do! Seriously - otherwise, how do I learn how to improve?

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
 
Reply With Quote
 
JKop
Guest
Posts: n/a
 
      07-21-2004
Christopher Benson-Manica posted:

> JKop <(E-Mail Removed)> spoke thus:
>
>> Without passing judgement on your design:

>
> No, please do! Seriously - otherwise, how do I learn how to improve?
>


First I'm going to talk about enums. They're pretty much useless. For
instance:

enum Month
{
Jan = 1,
Feb = 2,
Mar = 3,
Apr = 4,
May = 5,
Jun = 6,
Jul = 7,
Aug = 8,
Sep = 9,
Oct = 10,
Nov = 11,
Dec = 12
};

int main()
{
Month my_super_duper_month(13);
}


So why are they useful? They're only merit is with switch statements:


switch (some_month)
{
case Jan:
//blah
case Feb:

//blah

}


The compiler can warn you when you leave one out of the switch statement.
Yipee!

Anyway, I'd suggest you return an "unsigned char" from this function. If you
want to give certain numbers special names, then by all means:

namespace ChocolateValues
{
const unsigned char no_error = 0;
const unsigned char multiple_errors = 1;
};

unsigned char SomeFunction()
{
return ChocolateValues::no_error;
}




-JKop
 
Reply With Quote
 
Mark A. Gibbs
Guest
Posts: n/a
 
      07-22-2004

JKop wrote:
> First I'm going to talk about enums. They're pretty much useless. For
> instance:


you have some serious misconceptions about enumerations.

> enum Month
> {
> Jan = 1,
> Feb = 2,
> Mar = 3,
> Apr = 4,
> May = 5,
> Jun = 6,
> Jul = 7,
> Aug = 8,
> Sep = 9,
> Oct = 10,
> Nov = 11,
> Dec = 12
> };
>
> int main()
> {
> Month my_super_duper_month(13);
> }


compiler error - illegal implicit conversion to int.

mind you:

Month m(static_cast<Month>(13));

would work. but that is a case of directly and maliciously circumventing
the enumeration.

> So why are they useful? They're only merit is with switch statements:
>
>
> switch (some_month)
> {
> case Jan:
> //blah
> case Feb:
>
> //blah
>
> }
>
>
> The compiler can warn you when you leave one out of the switch statement.
> Yipee!


what compiler? i would find it quite bizarre if a compiler barked that
warning at me, unless it had some crazy super verbose warning setting.
it is not an error, or even a mistake, to only switch on certain
enumerators.

> Anyway, I'd suggest you return an "unsigned char" from this function. If you
> want to give certain numbers special names, then by all means:
>
> namespace ChocolateValues
> {
> const unsigned char no_error = 0;
> const unsigned char multiple_errors = 1;
> };
>
> unsigned char SomeFunction()
> {
> return ChocolateValues::no_error;
> }


and this has to be the wackiest suggestion of all, considering that you
write off enums for having an implicit conversion to int above (which
they don't, as i pointed out).

in fact, the example above is LESS robust than if it had used enums.
consider this:

////////////////////////////////////////////////////////

namespace error {
const unsigned char no_error = 0;
const unsigned char out_of_memory = 1;
const unsigned char cannot_open_file = 2;
}

enum type {
no_error,
out_of_memory,
cannot_open_file
};

void print_error(unsigned char c) {
// print error message based on error code
switch (c) {
case error::no_error: // whatever
case error:ut_of_memory: // whatever
case error::cannot_open_file: // whatever
// ...
}
}

// nothing seems wrong with this...
unsigned char oops = 3;

// ...but
print_error(oops); // <--- what should this do?

////////////////////////////////////////////////////////

as opposed to:

////////////////////////////////////////////////////////

namespace error {

enum type {
no_error,
out_of_memory,
cannot_open_file
};

}

void print_error(error::type c) {
// print error message based on error code
switch (c) {
case error::no_error: // whatever
case error:ut_of_memory: // whatever
case error::cannot_open_file: // whatever
// ...
}
}

error::type nope = 3; // won't compile

// this is explicit and obvious - the programmer knew what (s)he
// was doing, and should be able to explain him/herself
error::type iffy = static_cast<error::type>(3);

error::type ok = error:ut_of_memory; // obviously ok

////////////////////////////////////////////////////////

enumerations are not perfect - personally, i was looking for a better
solution just last week, and i was not satisfied with the options - but
until the standard committee gives the thumbs up to the new super enums,
we're stuck with them. despite all their shortcomings though, i'd have
to say they're still a better choice than simple ints (or unsigned
char's for that matter).

indi

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
What do we call things like Class, Interface, Enumerations etc Chanchal Java 4 11-29-2005 04:36 PM
Help - Using enumerations in a case statement exquisitus Java 2 04-24-2005 10:22 PM
#defines and enumerations in Java - How ? exquisitus Java 12 02-19-2005 03:27 PM
XML Schema - How to do a key-value map with 2 enumerations? Joyce XML 1 02-18-2005 07:43 PM
HttpStatusCode Enumerations... clintonG ASP .Net 4 05-06-2004 02:39 PM



Advertisments