How to use C++11 enum class for flags - c++

Say I have such a class:
enum class Flags : char
{
FLAG_1 = 1;
FLAG_2 = 2;
FLAG_3 = 4;
FLAG_4 = 8;
};
Now can I have a variable that has type flags and assign a value 7 for example? Can I do this:
Flags f = Flags::FLAG_1 | Flags::FLAG_2 | Flags::FLAG_3;
or
Flags f = 7;
This question arises because in the enum I have not defined value for 7.

You need to write your own overloaded operator| (and presumably operator& etc.).
Flags operator|(Flags lhs, Flags rhs)
{
return static_cast<Flags>(static_cast<char>(lhs) | static_cast<char>(rhs));
}
Conversion of an integer to an enumeration type (scoped or not) is well-defined as long as the value is within the range of enumeration values (and UB otherwise; [expr.static.cast]/p10). For enums with fixed underlying types (this includes all scoped enums; [dcl.enum]/p5), the range of enumeration values is the same as the range of values of the underlying type ([dcl.enum]/p8). The rules are trickier if the underlying type is not fixed - so don't do it :)

It's maybe better to make use of std::underlying_type instead of hard-coding char type.
Flags operator|(Flags lhs, Flags rhs) {
return static_cast<Flags>(
static_cast<std::underlying_type<Flags>::type>(lhs) |
static_cast<std::underlying_type<Flags>::type>(rhs)
);
}
Now, you can change the underlying type of your enumeration without needing to update that type in every bitwise operator overload.

It should handle any enumeration type. I'm not sure it doesn't have any side effects and is completely valid C++ code. Let me know if there are some issues.
template<class T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
constexpr T operator|(T lhs, T rhs)
{
return static_cast<T>(
static_cast<std::underlying_type<T>::type>(lhs) |
static_cast<std::underlying_type<T>::type>(rhs));
}

Please don't do this. If you need to do this, enum classs probably aren't what you need.
#T.C. showed you how to do it so long as you specify underlying type, but you will run into places where your program does things it just shouldn't.
An example is where you use a switch and have a case for every defined enum value.
e.g.
enum class my_enum: unsigned int{
first = 1,
second = 2,
third = 4,
fourth = 8
};
int main(){
auto e = static_cast<my_enum>(static_cast<unsigned int>(my_enum::first) | static_cast<unsigned int>(my_enum::second));
switch(e){
case my_enum::first:
case my_enum::second:
case my_enum::third:
case my_enum::fourth:
return 0;
}
std::cout << "Oh, no! You reached a part of the program you weren't meant to!\n";
return 1;
}
Will output:
Oh, no! You reached a part of the program you weren't meant to!
then return the error code 1.
Which is also an example of why you should always have a default case, of course, but that isn't my point.
Of course, you could argue that so long as the user of the enum class never directly uses the value other than passing to a function; it would be a good way of restricting the values of a bitset. But I've always been a little too trustworthy and find std::uint[n]_t and some constexpr variables the best way (if a user sets an invalid bit it simply does nothing).
What you're doing just isn't really suitable for enum class, because it defeats the purpose of having a scoped enumeration. You can no longer enumerate the values if you set it to an undefined one.

I realize this question is a bit old, but I will write out a method I have used to do this.
(If anything, if I Google this again in the future I have it documented to find again.)
Personally I like this method because intellisense (at least the VSCode version of it... I don't have Visual Studio on Linux...) will automatically pick up on what you're doing and give you useful hints. Also, it avoids the use of macros, so the compiler can warn you if it is not happy. Lastly, without the comments, it isn't a lot of code. You're not making a class and setting a bunch of overloads or anything, but you're still getting the benefit of scoped enums so that you can reuse a flag name/value for another enum. Anyway onto the example.
namespace FlagsNS
{
/* This is an old/classic style enum so put it in a
namespace so that the names don't clash
(ie: you can define another enum with the values of
Flag_1 or Flag_2, etc... without it blowing up)
*/
enum Flags
{
Flag_1 = 1 << 0, //Same as 1
Flag_2 = 1 << 1, //Same as 2
Flag_3 = 1 << 2, //Same as 4
Flag_4 = 1 << 3 //Same as 8
};
}
/* This is telling the compiler you want a new "type" called Flags
but it is actually FlagsNS::Flags. This is sort of like using the
#define macro, except it doesn't use the preprocessor so the
compiler can give you warnings and errors.
*/
using Flags = FlagsNS::Flags;
//Later in code.... so int main() for example
int main()
{
//If you don't mind c-style casting
Flags flag = (Flags)(Flags::FLAG_1 | Flags::FLAG_2 | Flags::FLAG_3);
//Or if you want to use c++ style casting
Flags flag = static_cast<Flags>(Flags::FLAG_1 | Flags::FLAG_2 | Flags::FLAG_3);
//Check to see if flag has the FLAG_1 flag set.
if (flag & Flags::FLAG_1)
{
//This code works
}
}

The code in question doesn't compile. But you can do something like this,
enum class Flags : char
{
FLAG_1 = 1,
FLAG_2 = 2,
FLAG_3 = 4,
FLAG_4 = 8,
};
int main() {
Flags f = static_cast<Flags>(7);
Flags f1 = static_cast<Flags>( static_cast<char>(Flags::FLAG_1) | static_cast<char>(Flags::FLAG_2) | static_cast<char>(Flags::FLAG_3) );
return 0;
}
and it works

At this point, It probably makes sense to define your own class to handle this.
/** Warning: Untested code **/
struct Flag {
static Flag Flag_1;
static Flag Flag_2;
static Flag Flag_3;
static Flag Flag_4;
Flag operator = (Flag);
private:
char const value;
};
Flag operator | (Flag, Flag);

Related

Default case compilation when switching over all items of an enum class

Why does the following switch even compiles the default case since it covers all items of the enum class?
I would have thought that this was the reason for having strong enum class in the first place.
As to why I would like to have a default even though I know that I cover all cases : This safe-guards me against my future careless-ness (and that of other coworkers)
enum class E {
a,
b
};
int main()
{
E c = E::b;
switch (c) {
case E::a:
case E::b:
std::cout << "pass" << std::endl;
break;
default:
static_assert(false, "This explodes!");
}
}
Proof
Because the compile can't know if someone casted an illegal value to the enum type. Consider:
E c = static_cast<E>( 42 );
The cast will compile without a warning (or even an error) as you are explicitly telling the compiler "I know what I'm doing, don't check the value". In practice, this sadly happens more often than you think. :(
Also, all code needs to be valid, even if it is later removed as unreachable. A static_assert(false,...) will fire at compile-time, independent of what would happen at run-time.
Enums are not restricted to the values that you name. They are restricted to values that fit in the underlying type, which is an integral type large enough to hold all the values. For example:
enum flags {
first = 0x01,
second = 0x02,
third = 0x04,
fourth = 0x08
};
flags operator | (flags f0, flags f1) {
return flags((int)f0 | (int)f1);
}
flags f = first | second; // okay; f holds 0x03

Advantage of array of enum over constant and macro? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Should I use #define, enum or const?
Advantage and disadvantages of #defines vs. constants?
How enum will be more useful than #define and const.
memory and code visibilty point of view and readability point of view.
can I convert (type cast) enum to array of int, If I have taken all value within integer.
Example:
class MapPlt_clContainer {
public:
enum tagVectorType {
enVTAll = 0,
enVTPolygon,
enVTLines
}
};
tVoid MapPlt_clRender::vDrawLineClass( MapPlt_clContainer::tagVectorType* )
While calling function enum pass
vDrawLineClass( ClassArray_Group ); //Working
While calling array base address pass
int test[3] =
{
5,
6,
7,
};
vDrawLineClass( test); //Not Working
Error!!
Should it type cast it automatically? or it is compiler dependent. In my case it is giving error.
enum is a separate type unlike #define and the language (with the help of compiler) will help you ensure you are not mixing values of different types (even if they are of the same numerical value).
Additionally the value of an enum is available to the debugger whereas the original meaning of the #define is lost during the pre-processing time (before the code generation has even begun).
Type-casting an enum to an int is an automatic built-in process while the opposite conversion is trickier as not all the int values could be valid for your particular enum.
Modern compilers will also warn you if you have used all the possible enum's values in a switch statement that has no default clause, something that cannot be checked for #defines
If you are using an enum as an integer in C++ you have a smell. An enum defines a type, and only the values of that type should be used. (I realize this isn't enforced and the enum can be interpreted as an int, but with C++ it generally shouldn't).
Also, a big pet peeve of mine: Don't put "Type" in the name for an enum in C++. The values of an enum are not "types" (in the C++ sense of the word). As soon as you start doing template code, you will HATE all the enums with the word Type in their type name.
Also, any time you are trying to typecast in your design, you are doing it wrong. That is an awful smell in C++. You shouldn't have to do it, and you certainly shouldn't design it into your code (i.e. use it as a "feature").
Finally, this part:
int test[3] =
{
5,
6,
7,
};
vDrawLineClass( test); //Not Working
This is a straight up ugly hack. Do what you say, say what you do:
MapPlt_clContainer::tagVectorType test[3] =
{
MapPlt_clContainer::enVTAll,
MapPlt_clContainer::enVTPolygon,
MapPlt_clContainer::enVTLines
};
vDrawLineClass( test);
In addition to the points made in other answers, I would like to add the following:
If you have multiple types and you need to iterate on them, you will have to use an array of constants, which will be something like this:
const int states[] = {STATE_1,STATE_2, STATE_3, STATE_4 };
int numStates = sizeof(states)/sizeof(state[0]);
for (int i = 0; i < numStates; i++) {
// Do something with states[i]..
}
With enumerations, this can be simplified as
enum states{cState_1 = 0, cState_2, cState_3, cState_4, cNumStates};
for (int i = 0; i < numStates; i++) {
// do something with i
}

Why can't I increment a variable of an enumerated type?

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.

Use Enum or #define?

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 *.

Enum C++ Get by Index

I was wondering in C++ if I have an enum can I access the value at the second index? For example I have
enum Test{hi, bye};
if I want 'hi', can I do something like Test[0], thanks.
Yes and no. If your Enum does not have explicit values then it is possible. Without an explicit values, enum values are given numeric values 0-N in order of declaration. For example ...
enum Test {
hi, // 0
bye // 1
}
This means that indexes just translates into a literal value.
Test EnumOfIndex(int i) { return static_cast<Test>(i); }
This of course does 0 validation at runtime and as soon as you add an explicit value it will break down. But it will work in the default scenario.
Unless specified otherwise, enums start numbering at 0, and increment by 1 each entry.
enum Test
{
hi, //0
bye, //1
count //2
}
You can cast an int to the type of the enum to get the value you want, such as:
(Test)0;
//or
Test(0);
Which lets you do things like:
for(int i = 0; i < count; i++)
{
DoSomething((Test)i);
}
Enumerations map names to values. In your case, (int)hi would have a value of 0, and (int)bye a value of 1. You can use a cast to get the value of hi:
int myInteger = 0;
Test myValue = (Test)myInteger;
Note, though, that myValue could be an invalid enum value if myInteger is out of range.
No, but you could cast from int
Test test = (Test)0;
Depends what you mean by "I want 'hi'".
If you mean you want the value, then you can get it by casting an int, as others have said.
Casting a numeric literal to enum type is usually pointless - if you know which value you're expecting, you can use the name. That way, the enum can change without breaking your code. I guess it's possible that something really weird is going on, where someone has created an enum, and documented what "3" means but not which enum value it is. But then you'd want to fix the API.
Casting an integer value known at runtime to enum might be helpful if you have serialized data. As long as you know it's in range of the enum, the result is defined.
If you mean you want the string "hi", then you can't have it. Unlike Java, in C++ the names of the values in enumerated types exist only at compile time, not at runtime, and only map in one direction.
Your best option might be something like this:
enum Test{hi = 0, bye};
Then you can simply refer to 'hi' with the number 0, and 'bye' with 1.
Although this really defeats the whole purpose of using an enumeration in the first place.
If you are excepting the value to returned as {Hi or bye} ,then you cannot get the value like that .
i would not suggest this to be done inorder to get the actual value but it can be used as hack
string return_value(int index)
{
string temp = "";
switch (index)
{
case 1: temp = "hi"
break;
case 2: temp = "bye";
break;
defualt :
break;
}
return temp;
}
typecasting to enum would again return the index but you can assign to some other enum variable
#include <iostream>
#define GENERATE_ENUM(ENUM) ENUM,
#define GENERATE_STRING(STRING) #STRING,
#define FOREACH_TEST(ID) ID(hi) ID(bye) ID(good)
enum TEST { FOREACH_TEST(GENERATE_ENUM) };
static const char * Test[] = { FOREACH_TEST(GENERATE_STRING) };
int main() {
printf("%s ",Test[0]);
printf("%s\n",Test[bye]);
for (int i=0; i<2; i++) printf("Test[%d] = %s\n", i, Test[i]); }
compile and run with: g++ enum-test.cpp -o enum-test; ./enum-test
output:
hi bye
Test[0] = hi
Test[1] = bye