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. 21 1900
On 21/7/04 8:46 pm, in article cd**********@chessie.cirr.com, "Christopher
Benson-Manica" <at***@nospam.cyberspace.org> 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.
On 21/7/04 8:50 pm, in article BD*****************@127.0.0.1, "Steve"
<ro**@127.0.0.1> wrote: On 21/7/04 8:46 pm, in article cd**********@chessie.cirr.com, "Christopher Benson-Manica" <at***@nospam.cyberspace.org> 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.
Steve <ro**@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.
Christopher Benson-Manica wrote: Steve <ro**@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
Peter van Merkerk <me*****@deadspam.com> 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.
Without passing judgement on your design:
extern enum bar;
return bar(0);
-JKop
JKop <NU**@null.null> 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.
Christopher Benson-Manica posted: JKop <NU**@null.null> 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
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::out_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::out_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::out_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
Christopher Benson-Manica wrote: Peter van Merkerk <me*****@deadspam.com> 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?
I'm afraid not.
--
Peter van Merkerk
peter.van.merkerk(at)dse.nl
Mark A. Gibbs posted: would work. but that is a case of directly and
maliciously circumventing the enumeration.
Month blah = Month(13);
error::type nope = 3; // won't compile
= EnumName(3); //*will* compile, regardless if the enum
contains a 3.
-JKOp
JKop <NU**@null.null> spoke thus: = EnumName(3); //*will* compile, regardless if the enum contains a 3.
Granted, but why on earth would you want to do *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.
Peter van Merkerk <me*****@deadspam.com> spoke thus: I'm afraid not.
No, no need to be afraid ;)
--
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.
On Wed, 21 Jul 2004 19:46:21 +0000 (UTC), Christopher Benson-Manica
<at***@nospam.cyberspace.org> 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?
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)?
All definitions of bar must be token for token identical according to
the one definition rule. If they aren't, you've got undefined
behaviour.
In your case you might just want to return some named constants, and
have other TUs cast them to whatever enum type they want (and
presumably a different one for each TU).
Tom
Christopher Benson-Manica posted: JKop <NU**@null.null> spoke thus:
= EnumName(3); //*will* compile, regardless if the enum
contains a 3.
Granted, but why on earth would you want to do *that*?
Because it can be done. If you write a function that takes
a month, then you've to check that it's >= 1 and <= 12.
Therefore, what use has an enum? Why not just use constant
variables?
namespace Month{
const unsigned char jan = 1,
feb = 2,
mar = 3,
apr = 4,
may = 5,
jun = 6,
//and so on
-JKop
JKop <NU**@NULL.NULL> wrote in news:zh*****************@news.indigo.ie: Christopher Benson-Manica posted:
JKop <NU**@null.null> spoke thus:
= EnumName(3); //*will* compile, regardless if the enum contains a 3. Granted, but why on earth would you want to do *that*?
Because it can be done. If you write a function that takes
So can dereferencing a NULL pointer, and reinterpret_casting stuff between
incompatable types. Doesn't mean that it's defined behaviour.
a month, then you've to check that it's >= 1 and <= 12. Therefore, what use has an enum? Why not just use constant variables?
No you don't. Your function simply takes a Month as a parameter. No need
to check for range. Your caller would have to invoke undefined behaviour
to break your function then.
"Christopher Benson-Manica" <at***@nospam.cyberspace.org> wrote in message
news:cd**********@chessie.cirr.com... JKop <NU**@null.null> spoke thus:
= EnumName(3); //*will* compile, regardless if the enum contains a 3.
Granted, but why on earth would you want to do *that*?
I think he means, how would you keep a user from inadvertently doing that
via a compiler error.
Jeff F
Andre Kostur <nn******@kostur.net> wrote:
[snip - debate over whether to use 'enum' for month names] No you don't. Your function simply takes a Month as a parameter. No need to check for range. Your caller would have to invoke undefined behaviour to break your function then.
If an enum contains values 1...11, then it can also hold values 12...15
without causing undefined behaviour. This language rule exists to allow
'flag' enums, eg:
enum flags
{
Foo = 0x80,
Bar = 0x40,
Quz = 0x20,
};
flags f = Foo | Quz; // 0xA0 is not an enum member, but is valid
So you still have to check range (> 0 as well as <= 12) ol*****@inspire.net.nz (Old Wolf) wrote in
news:84**************************@posting.google.c om: Andre Kostur <nn******@kostur.net> wrote:
[snip - debate over whether to use 'enum' for month names]
No you don't. Your function simply takes a Month as a parameter. No need to check for range. Your caller would have to invoke undefined behaviour to break your function then.
If an enum contains values 1...11, then it can also hold values 12...15 without causing undefined behaviour. This language rule exists to allow 'flag' enums, eg:
I stand corrected. The enum may contain values beyond the specified ones.
I guess, for me, that would leave it in the realm of "bad programming
practice". One would need to explicitly do something to put the enum out
of range (explicit construction with an out of range value, or do some sort
of bitwise or arithmetic operations on the enums)
JKop wrote: Because it can be done. If you write a function that takes a month, then you've to check that it's >= 1 and <= 12.
"because it can be done" is not a good reason for doing something. i
fail to see what would inspire an otherwise level-headed programmer to
randomly construct an illegal enumeration. why explicitly construct at
all? it makes little sense. and if you decide you *must* explicitly
construct an enumerator, why pick a raondom value like 13? why not just
use an existing enumerator value, like "feb"?
do you hang around programmers that randomly assign spurious values to
obviously logically incompatible types (there is no month "13", just
like there is no month "6" or "100", but there is a "may")?
Therefore, what use has an enum? Why not just use constant variables?
namespace Month{ const unsigned char jan = 1, feb = 2, mar = 3, apr = 4, may = 5, jun = 6, //and so on
because, as i showed you before, they are less safe than enumerators. no
one ever claimed enumerations cannot be broken, but at least when you
break an enumerator, it's not likely to be by accident. on the other hand:
unsigned char c = 42;
// lots of code in between
month m = c; // not a squeak from the compiler
// the only way you could break this with enums is
// if you did month m = static_cast<month>(c);
// or at least month m = month(c);
// which is pretty hard to miss
or:
namespace a {
typedef unsigned char month;
static const unsigned char jan = 0;
static const unsigned char feb = 1;
}
namespace b {
typedef unsigned char month;
static const unsigned char jan = 1;
static const unsigned char feb = 2;
}
b::month get_month()
{
using namespace a;
return jan; // but which jan?
// an enum version would not compile
}
and finally, let's assume that i thought that it would be reasonable for
a programmer to write month(13). in the enum version, modern ide's would
show you (via a tooltip or something) the name of the enumerator if it
was valid, and a number otherwise. in other words, you can debug just by
hovering the mouse over your suspect variable. you can't do that with
unsigned char's.
but i'll tell you what, i'll be open-minded about this. show me one (1)
real world error caused by any practical usage of enum that would be
fixed if the code were *identical* except the enum type were unsigned
char and the enumerators were static constants. by my count i've shown
you four code sample that demonstrate that enums are safer. all i ask
from you is one.
mark
I got around this by writing a Month class that validates
input on assignment and construction.
-JKop This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Joyce |
last post by:
In my schema I have 2 enumerations, let's say, country description and
country code, and I want to use them so I can map each country
description to its precise country code (and no other).
So far...
|
by: Plinkerton |
last post by:
I'm making an Base Class that will be inherited. In my base class, I
have a public enumeration that defines a list of things I want my class
to be able to do. I use it for Method input...
|
by: JoeH |
last post by:
Hi,
I'm using a COM DLL (created in VB) in my javascript code and can
successfully call its methods and get/set its properties. There are
also some Public enumerations defined in the ActiveX...
|
by: Seamus M |
last post by:
I can't find any info on enumerations in the PHP manual, so I assume there
is no built in way to create them. Can anyone tell me the best way to build
a simple enumeration, such as:
Enum...
|
by: someone else |
last post by:
I have some code that creates dynamic enumerations for use in a PropertyGrid
control. This all works perfectly but the memory usage of the program
increases quite quicly when viewing the...
|
by: Oleg Ogurok |
last post by:
Hi all,
I've added a new DataSet (xsd file) to my project in VS.NET 2003.
There I create a simple type as an enumeration of values.
<xs:simpleType name="MyCustomType">
<xs:restriction...
|
by: ChrisB |
last post by:
Hello:
I will be creating 50+ enumerations related to a large number of classes
that span a number of namespaces. I was wondering if there are any "best
practices" when defining enumerations.
...
|
by: Ben Finney |
last post by:
Antoon Pardon wrote:
> I just downloaded your enum module for python
> and played a bit with it. IMO some of the behaviour makes it less
> usefull.
Feedback is appreciated. I'm hoping to...
|
by: Ben Finney |
last post by:
Howdy all,
PEP 354: Enumerations in Python has been accepted as a draft PEP. The
current version can be viewed online:
<URL:http://www.python.org/peps/pep-0354.html>
Here is the...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
| |