C++ enumerate August 3rd, 2021 in programming Last updated on: December 16th, 2021 Mapping enumerate value to a string In C, normally when you want to map a enumerate value to a string, to print it, we can implement like this.
typedef enum {
none = 0 ,
pass ,
fail
} enVerdictValueType ;
const char * VERDICT_STR [] = {
[ none ] = "NONE" ,
[ pass ] = "PASS" ,
[ fail ] = "FAIL"
}
void func ( enVerdictValueType val )
{
// because of enum type, some time we could push int value to variable "val"
// incase of val receive from other source, it could cause out of array access if we don't check it carefully
printf ( "VERDICT: %s \r\n " , VERDICT_STR [ val ]);
}
Let try to improve above print enum implementation in C++.
#include <vector>
// create a general class that will do the enumerate mapping with string and do the checking
class EnumMap
{
private:
// vector to store the const string for enum map
std :: vector < const char *> table ;
// string to print when input enum value is out of index range
const char * ERROR_STRING = "OUT_OF_RANGE" ;
public:
// && is rvalue reference, specify rvalue because we initialize
// the string vector table with rvalue
EnumMap ( std :: vector < const char *>&& input_table )
: table ( std :: move ( input_table )) {}
~ EnumMap () {}
// override the operator []
const char * operator []( ssize_t idx ) const
{
// index checking
if (( idx < 0 ) || (( size_t ) idx > table . size ()))
{
// return ERROR string incase of input value is not exist in enum type
return ERROR_STRING ;
}
else
{
// return corresponding string
return table [ idx ];
}
}
};
// here is the part we using
// create enum
typedef enum {
none = 0 ,
pass ,
fail
} enVerdictValueType ;
// create corresponding enum string map with easier syntax
const EnumMap VERDICT_STR ({ "NONE" , "PASS" , "FAIL" });
// use it
>> std :: cout << VERDICT_STR [ pass ] << std :: endl ;
How about when you have a enumerate with its value does not span continuously, We could modify the EnumMap to use std::unordered_map<int, std::string> instead of std::vector
#include <unordered_map>
typedef enum {
none = 0 ,
pass = 22 , // << weird, but could happen
fail = 12
} enVerdictValueType ;
const EnumMap VERDICT_STR ({
{ none , "NONE" }, // << have to provide the index corresponding with string
{ pass , "PASS" },
{ fail , "FAIL" }});
class EnumMap
{
private:
// unordered_map to store the const string for enum map
std :: unordered_map < int , const char *> table ;
// string to print when input enum value is not existed
const char * ERROR_STRING = "OUT_OF_RANGE" ;
public:
// && is rvalue reference, specify rvalue because we initialize
// the string vector table with rvalue
EnumMap ( std :: unordered_map < int , const char *>&& input_table )
: table ( std :: move ( input_table )) {}
~ EnumMap () {}
// override the operator []
const char * operator []( ssize_t idx ) const
{
// index checking
if ( 0 == table . count ( idx ))
{
// return ERROR string incase of input value is not exist in enum type
return ERROR_STRING ;
}
else
{
// return corresponding string
return table . at ( idx );
}
}
};
Above class implementation help us initialize enumerate string map easier and less error-prone.