I have theenumerated type, colors:
enum colors {green, red, blue};
Is colors mycolors=red the same as int yourcolors=red and is the type of each enumerator int? The both will have a value of 1, right?
Thanks!
I just want to post a little code snippet to prove the comments of Jason Lang and Kerrek SB:
#include <iostream>
#include <typeinfo>
enum colors {green, red, blue};
int main()
{
colors mycolors=red;
int yourcolors=red;
if (mycolors == yourcolors)
std::cout << "same values" << std::endl;
if (typeid(mycolors) != typeid(yourcolors))
std::cout << "not the same types" << std::endl;
return 0;
}
Running this code will lead into the following console output:
same values
not the same types
Also (as Daniel Kamil Kozar mentioned) there is enum class (only C++11 and later!). See this Question for more information about why to prefer enum class over enum.
Regarding the question 'why are enums after not just ints (or longs or ...) just think of operator overloading. That is ++ colors(green) == 1 must not be true.
Confirm this Question that operator overloading is possible for plain enums and this question and the accepted answer to see how to avoid casting in overloading operators of an 'enum class'.
At last keep in mind that the usage of enums - if used reasonable - improves code readability.
I think enum seems a little more type-safety. You can do int yourcolors=red, but not colors mycolors=1.
When I'm debugging enum usage is helpful. It shows enumeration name
instead of its value.
Enumeration values aren’t lvalues. So, when you pass them by
reference, no static memory is used. It’s almost exactly as if you
passed the computed value as a literal.
enum KEYS
{
UP,
RIGHT,
DOWN,
LEFT
};
void (KEYS select)
{
switch (select)
{
case UP:
case RIGHT:
case DOWN:
case LEFT: break;
default: exit(1);
}
}
Related
This is maybe a bit weird question, but I really don't know how to phrase it better than this.
I just discovered that I can do the following:
#include <iostream>
enum class Colour // also works with plain old enum
{
Red = 1,
Green,
Blue,
Yellow,
Black,
White
};
int main()
{
Colour c = Colour(15); // this is the line I don't quite understand
std::cout << static_cast<int>(c) << std::endl; // this returns 15
return 0;
}
So now I have integer value 15 in a variable of the type Colour.
What exactly is happening here? Is that some kind of enum "constructor" at work? As far as I know, integer value 15 is not put into enumeration, it is stored just in variable c. Why would something like that be useful, in the first place - to create a value that doesn't exist in enum?
Colour(15) is an expression that creates a temporary (prvalue) instance of the Colour enum, initialized with the value 15.
Colour c = Colour(15); initializes a new variable c of type Colour from the previously-explained expression. It is equivalent to Colour c(15).
What's happening here is that strongly-typed enums in C++11 are still capable of holding out-of-range values if you explicitly cast or default initialize them. In your example Colour c = Colour(15); is perfectly valid even though Colour only has meaningful values for 1-6.
I am currently building a poor version of the game "Battleship" and have to use an array of Enums to display the board. For my header I have created:
enum class PlayerPiece {
AIRCRAFT,
BATTLESHIP,
CRUISER,
SUBMARINE,
PATROL,
EMPTY,
};
class Board {
public:
PlayerPiece playerBoard[100];
PlayerPiece enemyBoard[100];
void reset();
void display() const;
};
When I get to my source code, I try displaying the board as numbers. As of right now the board is EMPTY after I run my reset command. But after I want to display the array, I get an error saying "no operator << matches these operands ....", I understand that means I need to overload the << command to display properly, but why doesn't it just display the '5' that was assigned? Isn't that the point of Enums? What I have so far is:
void Board::reset(){
for (int i = 0; i < 100; ++i){
playerBoard[i] = PlayerPiece::EMPTY;
enemyBoard[i] = PlayerPiece::EMPTY;
};
}
void Board::display() const{
for (int i = 0; i < 100; ++i){
cout << playerBoard[i] << endl; //
};
}
I have made other codes where I don't have to overload the << operator to display the number attached with ENUM. Am I missing something? Any help would be appreciated.
If you want to see the number associated with the scoped enum type, use a static_cast like this:
cout << static_cast<int>(playerBoard[i]) << endl;
Normal (unscoped) enums don't need this cast, as their types implicitly cast to int, or whatever underlying type you specified. That's probably why this hasn't happened to you before.
If you remove the class and write enum with Unscoped enumeration
enum PlayerPiece {
AIRCRAFT,
BATTLESHIP,
CRUISER,
SUBMARINE,
PATROL,
EMPTY,
};
You can print the number you wanted.
The difference between scoped and unscoped(from cplusplus.com):
Before C++11, all enums were just, basically, integers. And you could use them like that. It made it too easy to give bad values to functions expecting a restricted set of values. For example:
1
2
3
4
5
6
7
8
9
10
enum round_mode { round_half_up, round_half_down, round_bankers };
double round( double x, round_mode = round_half_up )
{
...
};
int main()
{
double x = round( 2.5, 42 );
}
Edit & Run
It compiles, but it isn't pretty.
With C++11, the compiler now knows all kinds of things about your enums, and doesn't let you blithely mix them with incorrect values.
Essentially, it promotes an enum to a first-class object -- it isn't just an integer.
The other issue is that the name for each enumeration bleeds into the containing scope. So the following would be a name conflict:
1
2
enum color_masks { red = 0xFF0000, green = 0x00FF00, blue = 0x0000FF };
int red = 0xFF0000;
You can't have both the identifier 'red' as an enum value and as an integer variable name in the same scope.
While the example here is contrived, it isn't too far off from things that happen all the time -- and that programmers have to take pains to avoid.
(Some identifier names are common. For example, 'max'. If you #include , there's a 'max' macro in there, which plays havoc if you also #include and try to use the 'max' function, or #include and try to find the numeric_limit ::max(). I know that's a macro problem, but it's the first name conflict I could come up with...)
By default enumerated type variables take the size of integer i.e 4 bytes in memory. Is there any way to convert this to any other data type size.
Am not talking about type casting, but the memory size required to store an enumerated type.I have referred this question But it didn't tell about changing the integer size to any other.Any help.
c++11 introduced strongly typed enums (and Strongly Typed Enums (Revision 3)), which permits the specification of the underlying integral type:
#include <iostream>
enum E_ushort : unsigned short { EUS_1, EUS_2 };
enum E_ulong : unsigned long { EUL_1, EUL_2 };
int main()
{
std::cout << sizeof(E_ushort::EUS_1) << "\n";
std::cout << sizeof(E_ulong::EUL_1) << "\n";
return 0;
}
Output:
2
4
by reading some documentation on this website i think it's not possible. In fact it's logical. An enum list just a list with item's referenced by numbers. So, first question which type or you looking at? do you need an enum list who the nomber of item's are to bing for a int ? Or, are you looking at an other type like float char long.. in this case i don't think it's possible
I have a enumerated type StackID, and I am using the enumeration to refer to an index of a particular vector and it makes my code easier to read.
However, I now have the need to create a variable called nextAvail of type StackID. (it actually refers to a particular stackID ). I tried to increment it but in C++, the following is illegal:
nextAvail++;
Which sort of makes sense to me ... because there's no bounds checking.
I'm probably overlooking something obvious, but what's a good substitute?
I also want to link to this question.
I'm probably overlooking something obvious, but what's a good substitute?
Overloading operator++:
// Beware, brain-compiled code ahead!
StackID& operator++(StackID& stackID)
{
#if MY_ENUMS_ARE_CONTIGUOUS && I_DO_NOT_WORRY_ABOUT_OVERFLOW
return stackID = static_cast<StackID>( ++static_cast<int>(stackID) );
#else
switch(stackID) {
case value1 : return stackID = value2;
case value2 : return stackID = value3;
...
case valueN : return stackID = value1;
}
assert(false);
return stackID; // some compilers might warn otherwise
#endif
}
StackID operator++(StackID& stackID, int)
{
StackID tmp(stackID);
++stackID;
return tmp;
}
Because enumerations do not have to be contiguous. E.g. take this example:
enum Colors {
cRed, // = 0
cBlue, // = 1
cGreen = 3
}
What should happen in this scenario?
Colors color = cBlue;
Colors other = color++;
Should other be cGreen or should it be 2. In that case it's not a valid enumeration member anymore. What about this?
Colors color = cGreen;
Colors other = color++;
Should other be cRed (wrap around) or 4?
As you can see, being able to increment enumeration values introduces a whole lot of questions and complicates the simple mechanism that they intend to be.
If all you care about is the integer value being incremented, then simply cast to int and increment that.
Casting back and forth to/from int is of course the obvious solution, then you make clear that you understand that the addition is happening "outside" the enum:
nextAvail = static_cast<StackID>(static_cast<int>(nextAvail) + 1);
Why not store nextAvail as an int instead if you're going to do arithmetic operations on it?
Another option would be to wrap the enum in your own type and overload operator ++ for it (which also could wrap around or something for instance).
An enumeration is semantically supposed to represent a set of distinct related, values.
So you could have
enum Colour {RED, GREEN, BLUE};
But that should be equivalent to:
enum Colour {GREEN, BLUE, RED};
The problem is that if you increment an enum then those representations are not the same. GREEN++ in the first case is not the same as GREEN++ in the second.
Making your program dependent on the declaration of the enum is a recipe for disaster - maintainers may assume that the order of the enum doesnt matter, introducing many silent bugs.
Very Simple:
nextAvail = (StackID)(nextAvail + 1);
Enums are going to be type int, so you can cast them. Is this what you're trying to do?
int ndx = (int) StackID.SomeValue;
...
++ndx;
This is going to make someone very confused down the line, of course.
It occurs to me that you're using an enum where you should be using const, or even #define. enum is most appropriate when you have arbitrary values (where the exact value is not meaningful).
I've overloaded the ++/-- operator in this way:
enum STATE {STATE_1, STATE_2, STATE_3, STATE_4, STATE_5, STATE_6};
// Overload the STATE++ operator
inline STATE& operator++(STATE& state, int) {
const int i = static_cast<int>(state)+1;
state = static_cast<STATE>((i) % 6);
return state;
}
// Overload the STATE-- operator
inline STATE& operator--(STATE& type, int) {
const int i = static_cast<int>(type)-1;
if (i < 0) {
type = static_cast<STATE>(6);
} else {
type = static_cast<STATE>((i) % 6);
}
return type;
}
With respect to oprator++, $5.2.6/1 states- "The type of the operand shall be an arithmetic type or a pointer to a complete object type."
StackID does not fit the bill here. It is of enumeration type.
One option is like this
$5.7/1 - "For addition, either both operands shall have arithmetic or enumeration type, or one operand shall be a pointer to a completely defined object type and the other shall have integral or enumeration type."
enum Possibility {Yes, No, Maybe};
Possibility operator++(Possibility const& r){
return Possibility(r + 1); // convert r to integer, add 1, convert back to Enum
}
int main(){
Possibility p = Yes;
Possibility p1 = ++p;
}
I'm quite happy with this C plus C++ solution for a for loop incrementing an enum.
for (Dwg_Version_Type v = R_INVALID; v <= R_AFTER; v++)
=>
int vi;
for (Dwg_Version_Type v = R_INVALID;
v <= R_AFTER;
vi = (int)v, vi++, v = (Dwg_Version_Type)vi)
The other solutions here are not C backcompat, and quite large.
I'm building a toy interpreter and I have implemented a token class which holds the token type and value.
The token type is usually an integer, but how should I abstract the int's?
What would be the better idea:
// #defines
#define T_NEWLINE 1
#define T_STRING 2
#define T_BLAH 3
/**
* Or...
*/
// enum
enum TokenTypes
{
t_newline = 1,
t_string = 2,
t_blah = 3
};
Enums can be cast to ints; furthermore, they're the preferred way of enumerating lists of predefined values in C++. Unlike #defines, they can be put in namespaces, classes, etc.
Additionally, if you need the first index to start with 1, you can use:
enum TokenTypes
{
t_newline = 1,
t_string,
t_blah
};
Enums work in debuggers (e.g. saying "print x" will print the "English" value). #defines don't (i.e. you're left with the numeric and have to refer to the source to do the mapping yourself).
Therefore, use enums.
There are various solutions here.
The first, using #define refers to the old days of C. It's usually considered bad practice in C++ because symbols defined this way don't obey scope rules and are replaced by the preprocessor which does not perform any kind of syntax check... leading to hard to understand errors.
The other solutions are about creating global constants. The net benefit is that instead of being interpreted by the preprocessor they will be interpreted by the compiler, and thus obey syntax checks and scope rules.
There are many ways to create global constants:
// ints
const int T_NEWLINE = 1;
struct Tokens { static const int T_FOO = 2; };
// enums
enum { T_BAR = 3; }; // anonymous enum
enum Token { T_BLAH = 4; }; // named enum
// Strong Typing
BOOST_STRONG_TYPEDEF(int, Token);
const Token NewLine = 1;
const Token Foo = 2;
// Other Strong Typing
class Token
{
public:
static const Token NewLine; // defined to Token("NewLine")
static const Token Foo; // defined to Token("Foo")
bool operator<(Token rhs) const { return mValue < rhs.mValue; }
bool operator==(Token rhs) const { return mValue == rhs.mValue; }
bool operator!=(Token rhs) const { return mValue != rhs.mValue; }
friend std::string toString(Token t) { return t.mValue; } // for printing
private:
explicit Token(const char* value);
const char* mValue;
};
All have their strengths and weaknesses.
int lacks from type safety, you can easily use one category of constants in the place where another is expected
enum support auto incrementing but you don't have pretty printing and it's still not so type safe (even though a bit better).
StrongTypedef I prefer to enum. You can get back to int.
Creating your own class is the best option, here you get pretty printing for your messages for example, but that's also a bit more work (not much, but still).
Also, the int and enum approach are likely to generate a code as efficient as the #define approach: compilers substitute the const values for their actual values whenever possible.
In the cases like the one you've described I prefer using enum, since they are much easier to maintain. Especially, if the numerical representation doesn't have any specific meaning.
Enum is type safe, easier to read, easier to debug and well supported by intellisense. I will say use Enum whenever possible, and resort to #define when you have to.
See this related discussion on const versus define in C/C++ and my answer to this post also list when you have to use #define preprocessor.
Shall I prefer constants over defines?
I vote for enum
#define 's aren't type safe and can be redefined if you aren't careful.
Another reason for enums: They are scoped, so if the label t_blah is present in another namespace (e.g. another class), it doesn't interfere with t_blah in your current namespace (or class), even if they have different int representations.
enum provided type-safety and readability and debugger. They are very important, as already mentioned.
Another thing that enum provides is a collection of possibilities. E.g.
enum color
{
red,
green,
blue,
unknown
};
I think this is not possible with #define (or const's for that matter)
Ok, many many answers have been posted already so I'll come up with something a little bit different: C++0x strongly typed enumerators :)
enum class Color /* Note the "class" */
{
Red,
Blue,
Yellow
};
Characteristics, advantages and differences from the old enums
Type-safe: int color = Color::Red; will be a compile-time error. You would have to use Color color or cast Red to int.
Change the underlying type: You can change its underlying type (many compilers offer extensions to do this in C++98 too): enum class Color : unsigned short. unsigned short will be the type.
Explicit scoping (my favorite): in the example above Red will be undefined; you must use Color::Red. Imagine the new enums as being sort of namespaces too, so they don't pollute your current namespace with what is probably going to be a common name ("red", "valid", "invalid",e tc).
Forward declaration: enum class Color; tells the compiler that Color is an enum and you can start using it (but not values, of course); sort of like class Test; and then use Test *.