I am reading an enum
value from a binary file and would like to check if the value is really part of the enum
values. How can I do it?
#include <iostream>
enum Abc
{
A = 4,
B = 8,
C = 12
};
int main()
{
int v1 = 4;
Abc v2 = static_cast< Abc >( v1 );
switch ( v2 )
{
case A:
std::cout<<"A"<<std::endl;
break;
case B:
std::cout<<"B"<<std::endl;
break;
case C:
std::cout<<"C"<<std::endl;
break;
default :
std::cout<<"no match found"<<std::endl;
}
}
Do I have to use the switch
operator or is there a better way?
EDIT
I have enum values set and unfortunately I can not modify them. To make things worse, they are not continuous (their values goes 0, 75,76,80,85,90,95,100, etc.)
Maybe use enum like this:
and to check
If you don't specify values for enum constants, the values start at zero and increase by one with each move down the list. For example, given
enum MyEnumType { ALPHA, BETA, GAMMA };
ALPHA has a value of 0, BETA has a value of 1, and GAMMA has a value of 2.enum
value is valid in C++ if it falls in range [A, B], which is defined by the standard rule below. So in case ofenum X { A = 1, B = 3 }
, the value of2
is considered a valid enum value.Consider 7.2/6 of standard:
There is no retrospection in C++. One approach to take is to list enum values in an array additionally and write a wrapper that would do conversion and possibly throw an exception on failure.
See Similar Question about how to cast int to enum for further details.
The only way I ever found to make it 'easy', was to create (macro) a sorted array of the enums and checking with that.
The
switch
trick fail withenum
s because anenum
may have more than one enumerator with a given value.It's an annoying issue, really.
Speaking about a language, there is no better way, the enum values exist compile time only and there is no way to enumerate them programatically. With a well thought infrastructure you may still be able to avoid listing all values several times, though. See Easy way to use variables of enum types as string in C?
Your sample can then be rewritten using the "enumFactory.h" provided there as:
or even (using some more facilities already existing in that header):
In C++ 11 there is a better way if you are prepared to list your enum values as template parameters. You can look at this as a good thing, allowing you to accept subsets of the valid enum values in different contexts; often useful when parsing codes from external sources.
A possible useful addition to the example below would be some static assertions around the underlying type of EnumType relative to IntType to avoid truncation issues. Left as an exercise.
Yet another way to do it:
The "ugly" part of this approach IMHO is having to define:
If you are not opposed to macros, you can wrap it inside a macro: